总结和复习二

我对这周学到的知识做一个全面的总结,这周的学习对我的影响非常大,函数,字符串,类,列表等等都是非常重要的知识,由于我的思维能力较差所以对我来说这一块比较难,但我会尽力去克服困难。通过这周的学习让我明白了python这门语言的一些优势与缺点,比如它的垃圾回收能力非常出色,但是它也有许多坑,例如在交互式环境中如果两个变量等于一个数,那么这两个变量是同一个地址的数字区间在[-5,256],而在开发环境中这个区间变成0到无穷大,这种情况在java和C中不会出现。

函数

def is_palindrome(a):

    # 判断一个字符串是不是回文字符串
    """
    :param a: 一个字符串

    :return: 是回文字符串就返回True否则返回False
    """

    for b in range(len(a) // 2):
        if a[b] != a[len(a) - b - 1]:
            return False
    return True


if __name__=='__main__':
    print(is_palindrome('adcda'))
def f(*args):#可变参数
    total = 0
    for val in args:
        total += val
    return total

mylist = [1,3,5,45,67,54]
print(f(*mylist))
####定义判断质数的函数
from math import sqrt
def is_prime(num):
    for factor in range(2,int(sqrt(num))+1):
        if num%factor==0:
            return False
    return True if num!=1 else False
####as是在调入函数时的别名处理,让函数名更简单
import combination as ca
if __name__=='__main__':
    print(ca.gcd(15,27))
    print(ca.lcm(15,27))
#定义最大公约数的函数
def gcd(x,y):
    """
    计算两个数的最大公约数

    :param x: 一个正整数
    :param y: 一个正整数

    :return: x和y的最大公约数
    """
    (x,y)=(y,x) if (x>y) else (x,y)
    for factor in range(x,0,-1):
        if x%factor==0 and y%factor==0:
            return factor
定义最小公倍数的函数

def lcm(x,y):
return x*y//gcd(x,y)

def add(x=0,y=0,z=0):
return x+y+z

参数默认值为0

print(add())
print(add(x=1,z=2,y=3))

函数的参数个数可以有0个或任意多个
#可变参数
def f(*args):
    total = 0
    for val in args:
        total += val
    return total

mylist = [1,3,5,45,67,54]
print(f(*mylist))
判断一个数是不是回文数
def  is_palindrome(num):
    """
    判断一个数是不是回文数
    :param num: 一个非负整数
    :return: 是回文数返回True否则返回False
    """
    temp=num
    total=0
    while temp>0:
        total=total*10+temp%10
        temp//=10
    return num==total

if __name__=='__main__':
    number=int(input('请输入一个非负整数:'))

and和or运算符都是带短路功能的运算符
如果and左边的表达式是False那么右边的表达式被短路(不执行)
如果or左边的表达式是True那么右边的表达式被短路(不执行)
所以左右两边的表达式放置的顺序可能会对执行效率产生明显的影响

判断是不是回文质数
if is_prime(number) and is_palindrome(number):
    print('%d是回文素数' %number)
else:
    print('%d不是回文素数' %number)
驼峰命名法如下:
isPrime
ageOfStudent
variable:变量
constant:常量
#####人机拿火柴游戏
from random import randint
match=21
while match>1:
    print('剩余火柴数%d' %match)
    p=int(input('人拿的火柴数:'))
    if 1<=p<=4:
        match-=p
        print(match)
    j=5-p
    print('机器拿的火柴%d' %j)
    while True:
        match-=j
        break
print('人拿了最后一根,机器赢')
人跟机器都随机拿的写法:
from random import randint
match=21
while match>0:
    print('总共还有%d根火柴' %match)
    while True:
        num = int(input('人拿的火柴数:'))
        if 1<=num<=4 and num<=match:
            break
        else:
            print('请重新拿')
    match -= num
    if match>0:
        com = randint(1,min(4,match))
        print('计算机拿了%d根火柴' %com)
        match-=com
        if match == 0:
            print('计算机拿到最后一根火柴,你赢了!')
    else:
        print('你拿了最后一根火柴,你输了!')
函数作用域
在函数外面定义的a是一个全局变量(global variable)
python搜索一个变量的方式是从局部作用域到嵌套作用域再到全局作用域再到内置
Local-Enclosed-Global-Built
如果想改变搜索范围 可以使用global和nonlocal关键字
我们在做开发时要减少使用全局变量
迪米特法则:尽量减少与陌生的模块挂钩
a = 100

def  foo():
    #local variable
    # 函数内的局部变量  离开foo函数变量a是无法访问的,如果要让局部变量使用全局变量可以通过如下方法:
    #全局变量可以在整个项目使用,函数内的变量不能在函数外使用,要想达到这个效果用global关键字
    global a
    a = 200
    b = 'hello'


    def bar():
        nonlocal b
        b = 'good'
        print(a)
        print(b)


    bar()
    print(b)


foo()
print(a)
# 在进入函数调用之前要保存当前的执行现场
# 函数的执行现场是保存在一种称为栈(stack)的内存空间上
# 栈是一种先进后出(FILO)的存储结构
函数的递归调用
1.收敛条件:让递归在有限的次数内完成或者进行回溯
2.如果递归无法在有限的次数内收敛就有可能导致递归错误(RecursionError)
递归调用:一.个函数,调用了自身即是递归

三要素:
1.写出临界条件
2.返回上一级和下一级之间的关系
3.根据上一次计算出的结果求出本次计算的结果

def f(n):
    if n==0 or n==1:
        return 1
    return n*f(n-1)



def f(n):
    if n == 0:
        return 0
    return n+f(n-1)

if __name__ == '__main__':
    print(f(100))


def walk(n):
    if n<0:
        return 0
    elif n == 0:
        return 1
    return walk(n-1)+walk(n-2)+walk(n-3)

if __name__ == '__main__':
    print(walk(10))

#汉诺塔游戏
def hanoi(n,a,b,c):
    if n>0:
        hanoi(n-1,a,c,b)
        print(a,'.....',b)
        hanoi(n-1,c,b,a)
递归解决螺旋矩阵问题
n = int(input('请输入数字:'))
#初始化列表
list1 = [[0] * n for i in range(n)]
#递归解决
def fun(list1, x, y, start, n):
    if n<=0:return 0
    if n==1:
        list1[x][y] = start
        return 0
    #up
    for i in range(n):
        list1[x][y + i] = start
        start += 1
    #right
    for i in range(n-1):
        list1[x + 1 + i][y + n - 1] = start
        start += 1
    #down
    for i in range(n-1):
        list1[x + n - 1][y + n - 2 - i] = start
        start += 1
    #left
    for i in range(n-2):
        list1[x + n - 2 - i][y] = start
        start += 1
    fun(list1, x + 1, y + 1, start, n - 2)

a = fun(list1, 0, 0, 1, n)
#格式化输出print
len1 = len(str(n*n))+1
str1 = ('%'+str(len1)+'d')*n
for tmp in list1:
    print (str1 %tuple(tmp))

n=5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

递归目录,搜索出目录下的全部文件跟文件夹
import os
'''
getAllDir(path, str = '')
path: 文件路径
str: 路径字符串
'''
# 实现目录的遍历
def getAllDir(path, str = ''):
    # 返回一个指定文件夹(目录)包含文件和文件夹(目录),并且返回一个列表,但是不包含.和..,他一般按照英文首字母排序
    fillAll = os.listdir(path)
    # print(fillAll)
    str += ' '
    for filename in fillAll:

        # 一定不能少了全路径的拼接
        filePath = os.path.join(path, filename)
        # print(filePath)

        # 判断filePath是否是目录
        if os.path.isdir(filePath):
            print(str + '文件夹' + filename)
            # filePath是目录
            getAllDir(filePath, str)
        else:
            # filePath不是目录,即是文件
            print(str + '文件:' + filename)


getAllDir('..\day08')
使用栈模拟递归遍历目录
import os
def getALLDir(path):
    list1 = []
    list1.append(path)
    # print(list1)

    while len(list1) != 0:
        # 开始从列表中取数据
        dirPath = list1.pop()
        # print(dirPath)
        # 得到文件下边的所有文件路径
        filesAll = os.listdir(dirPath)

        # print(filesAll)

        for filename in filesAll:
            # 路径拼接全路径
            filePath = os.path.join(dirPath, filename)
            if os.path.isdir(filePath):
                # 是目录
                list1.append(filePath)

            else:
                # 是文件
                print('文件' + filename)

getALLDir('../day08')
使用队列模拟递归遍历目录
import os
import collections

def getAllDir(path):
    # 创建列表
    # 使用collections.deque方法可以创建一个两端都可以操作的列表,也就是说我们可以在两端进行添加和删除
    que = collections.deque()
    que.append(path)
    # print(que)

    while len(que) != 0:
        # 得到文件路径
        dirPath = que.popleft()

        # 获取该路径下边的文件和文件夹
        filesPath = os.listdir(dirPath)

        for filename in filesPath:
            # 拼接全路径
            filePath = os.path.join(dirPath, filename)

            if os.path.isdir(filePath):
                # 是目录
                que.append(filePath)
            else:
                # 是文件
                print('文件' + filename)

getAllDir('../day08')


模块

在python中,每一个脚本执行都会有一个__name__属性
1.如果当前脚本独立运行,则其name属性的值为__main__
2.如果当前脚本引入模块,则模块中的names属性值是当前模块名,而执行脚本的name属性值是__main__

####从不同模块调入同一个函数,则是后面的那一种生效。
####也可用下面这种两种方式来规避。
####通过下面的if条件可以在导入模块时不去执行下面的代码
if __name__=='__main__':
    from math import gcd
    print(gcd(2,3))
    from combination import gcd
    print(gcd(4, 6))
import math
import combination as ca #这里的as是对复杂模块名称的别名处理,让它用起来更简洁

from  day6 import is_prime
#####从模块导入全部函数用*
from day6 import *

if __name__=='__main__':
    for n in range(1,101):
        if is_prime(n):
            print(n)
#我们可以把程序中相对独立的功能模块抽取出来
#这样做的好处是减少重复代码的编写
#将来可以重复的使用这些功能模块
#python中的函数就是代表了这样的功能模块
#y=f(x) f是函数名 x是自变量 y是因变量
定义函数的括号内可以有1个或多个参数
定义函数时自变量也可以有默认值
定义求阶乘的函数,将求阶乘的功能抽取出来放到函数中
当需要计算阶乘的时候不用在写循环而是直接调用已经定义好的函数
os模块
#获取当前的工作目录
# 获取的是绝对路径
# print(os.getcwd())

# 在windows下,写路径尽量写成/
# print(os.listdir('C:/Users/刘海艳/Desktop/day09'))
# 直接报错,不能传递文件路径
# print(os.listdir('C:/Users/刘海艳/Desktop/day09/1-os模块.py'))


# 在当前目录下创建新的目录
# os.mkdir('C:/Users/刘海艳/Desktop/day09/lhy')
# os.mkdir('./goods')


# 删除目录, 只能删除空目录
# os.rmdir('goods')


# 对文件进行重命名
# os.rename('goods', 'bad')


# 获取文件的属性

# print(os.stat('1-os模块.py'))


# 删除文件
# os.remove('./bad/hello.py')
# os.remove('test.txt')

# 路径拼接

path1 = 'C:/Users/刘海艳/Desktop/day09/'
path2 = '/lhy'
# 注意:在参数二处尽量不要写/
# print(os.path.join(path1, path2))

# 拆分路径
# print(os.path.split('C:/Users/刘海艳/Desktop/day09'))
# # print(os.path.split('C:/Users/刘海艳/Desktop/day09/1-os模块.py'))


# 拆分文件的扩展名
path1 = 'C:/Users/刘海艳/Desktop/day09/1-os模块.py'
# print(os.path.splitext(path1))

# 判断是否是目录,是返回True  否返回False
# print(os.path.isdir(path1))

# 判断目录存在不存在
# print(os.path.exists(path1))

# 判断s是否是文件
# print(os.path.isfile(path1))

# 获取文件的大小
# print(os.path.getsize(path1))

# 获取当前文件的目录
# print(os.path.dirname(path1))

# 获取当前文件名
print(os.path.basename(path1))
时间模块
import time

# 时间戳 1970-1-1 00:00:00, 以浮点形式显示
time1 = time.time()
# print(time1)

# 将时间戳转换成UTC时间
time2 = time.gmtime(time1)
# print(time2)


# 将时间戳转换成本地时间
time3 = time.localtime(time1)
# print(time3)


# 将时间格式转换成时间戳 单位是S,  返回一个浮点数
time4 = time.mktime(time3)
# print(time4)

# 将时间格式转换成用户可读的时间形式  ,并且返回的是一个字符串
time5 = time.asctime(time3)
# print(time5)
# print(type(time5))

# 将时间戳转换成用户可读的时间.
time6 = time.ctime(time1)
# print(time6)
# print(type(time6))

# 字符串的格式化输出,一般展示给你的亲爱的用户来看
time7 = time.strftime('%Y-%m-%d %X', time2)
time8 = time.strftime('%Y-%m-%d %X', time3)
# print(time7)
# print(time8)

# 将字符串的时间格式转换成元祖类型的时间格式
time9 = time.strptime(time7,'%Y-%m-%d %X')
print(time9)
datetime模块
import datetime


date1 = datetime.datetime.now()
# print(date1)
# print(type(date1))

# 获取指定的时间
date2 = datetime.datetime(2028, 6, 6, 10, 23, 34, 234)
# print(date2)

date3 = date1.strftime('%Y-%m-%d %X') #格式化操作
# print(date3)


date4 = datetime.datetime.strptime(date3, '%Y-%m-%d %X') 将字符串转换成元组
print(date4)
日历模块
# 获取指定的月份
# print(calendar.month(2018, 5))

# 获取指定的年份
# print(calendar.calendar(2018))
#

# 参数一返回上个月的最后一天对应的星期
# 参数二返回当月的天数
# print(calendar.monthrange(2018, 6))

# 返回一个二级列表, 并且每个单独的二级列表是以周为单位
# print(calendar.monthcalendar(2018, 4))
文档注释 点击Ctrl+Q键可以看到函数的解释(如果是苹果系统用Ctrl+J)
def  f(x):
    """
    :param x: x是非负整数
    :return: x的阶乘
    """
      y=1
      for num in range(1,x+1):
          y*=num
      return y


if __name__=='__main__':
m=int(input('m='))
n=int(input('n='))
print(f(m)//f(n)//f(m-n))

字符串

字符串里的元素不可改变,可以进行切片操作:

def main():
    str1 = 'hello,world!'
    # 通过len函数计算字符串的长度
    print(len(str1))  12
    # 获得字符串首字母大写的拷贝
    print(str1.capitalize())  # Hello, world!
    # 获得字符串变大写后的拷贝
    print(str1.upper())  # HELLO, WORLD!
    # 从字符串中查找子串所在位置
    print(str1.find('or'))  # 7
    print(str1.find('shit'))  # -1
    # 与find类似但找不到子串时会引发异常
    # print(str1.index('or')) #7
    # print(str1.index('shit'))#报错
    # 检查字符串是否以指定的字符串开头
    print(str1.startswith('He'))  # False
    print(str1.startswith('hel'))  # True
    # 检查字符串是否以指定的字符串结尾
    print(str1.endswith('!'))  # True
    # 将字符串以指定的宽度居中并在两侧填充指定的字符
    print(str1.center(50, '*'))
    # 将字符串以指定的宽度靠右放置左侧填充指定的字符
    print(str1.rjust(50, ' '))
    str2 = 'abc123456'
    # 从字符串中取出指定位置的字符(下标运算)
    print(str2[2])  # c
    # 字符串切片(从指定的开始索引到指定的结束索引)
    print(str2[2:5])  # c12
    print(str2[2:])  # c123456
    print(str2[2::2])  # c246
    print(str2[::2])  # ac246
    print(str2[::-1])  # 654321cba
    print(str2[-3:-1])  # 45
    print(str2[:] #abc123456
    print(str2[::] #abc123456
    print(str2[:-2] #abc1234
    print(str2[::-2]#642ca
    print(str2[:-6:-1])  #65432
    # 检查字符串是否由数字构成
    print(str2.isdigit())  # False
    # 检查字符串是否以字母构成
    print(str2.isalpha())  # False
    # 检查字符串是否以数字和字母构成
    print(str2.isalnum())  # True
    str3 = '  jackfaruead@126.com '
    print(str3)
    # 获得字符串修剪左右两侧空格的拷贝
    print(str3.strip())
    #减掉左侧空格
    print(str3.lstrip())
    #减掉右侧空格
    print(str3.rstrip())
    str4=str3.replace('a','12',count=2)
    print(str4)  #'   j12ckf12ruead@126.com '
    replace有替换字符的作用
    swapcase()函数是将字符串中的大写转小写,小写转大写



if __name__ == '__main__':
    main()
用os模块做清屏处理
import os
import time

def main():
    str1 = '欢迎来到成都千峰学习......'
    while True:
        os.system('cls')
        print(str1)
        time.sleep(0.2)
        str1 = str1[1:] + str1[0]


if __name__ == '__main__':
    main()
生成四位随机验证码(可以是数字或大小写字母)
from random import randint

def generate(check_num = 4):
    """

    :param check_num: check_num:验证码的长度
    :return: 由大小写英文字母和数字构成的随机验证码
    """

    temp = ''
    for i in range(check_num):  # check_num为需要循环的次数,也就是需要生成验证码的个数,默认值为4
        choice = randint(1, 3)  # 生成1到3的随机数
        if choice == 1:  # 如果choice为1,则随机验证码的值为数字
            temp +=str(randint(0,9))
        elif choice == 2:  # 如果choice为2,则随机验证码的值为大写字母
            num = randint(65, 90)
            temp += chr(num)
        elif choice == 3:  # 如果choice为3,则随机验证码的值为小写字母
            num = randint(97, 122)
            temp += chr(num)
    return temp

if __name__ == '__main__':
    for _ in range(10):
        print(generate())
取文件的后缀名
def get_suffix(filename,has_dot = False):
    """

    :param filename: 文件名
    :param has_dot: 后缀名是否带.
    :return: 文件的后缀名
    """


    pos = filename.rfind('.')
    if 0 < pos < len(filename)-1 :
        index = pos if has_dot else pos+1
        return  filename[index:]
    else:
        return ''


if __name__ == '__main__':
    print(get_suffix('fdty.kdhd',True))

生成一个文件名

from random import randint

def main(x):
    temp = ''
    for _ in range(x):
        a = randint(1,3)
        if a == 1:
            temp += str(randint(0,9))
        elif a == 2:
            b = randint(65,90)
            temp += chr(b)
        elif a == 3:
            c = randint(97,122)
            temp += chr(c)

    return temp

if __name__ == '__main__':
    print(main(20))


列表

和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表。
f = [100,200,500]
for index,val in enumerate(f): # 枚举函数enumerate
print(index,’:’,val)
# CRUD操作Create Read Update Delete
f.append(123) # append表示在末尾加一个数
f.insert(2,90) # insert表示在f[2]的位置插入90这个元素
if 50 in f:
f.remove(50) # 如果不知道位置用这种删除
del f[3] # 如果知道位置用这种删除
#f.clear() 清除列表元素
print(f.index(200)) #输出200的下标
print(f.pop(1)) #删除下标为1的元素
f2 = [1,2,3]
f3 = f2.extend([4,5,6])
print(f3) #[1,2,3,4,5,6]
f4 = f2.extend((3,4))
print(f4) #[1,2,3,3,4]
f5 = f2.extend({‘name’:’熊彪’,’age’:25})
print(f5) #[1,2,3,’name’,’age’]
f7 = f2.extend((True,False))
print(f7) #[1,2,3,True,False]
f6 = f2.extend(5)
print(f6) #报错,extend里面必须是一个容器,不能直接加数字

import sys
f = [x**2 for x in range(1,10)]
print(sys.getsizeof(f)) #输出列表占用的内存
print(f)
f = [x+y for x in 'ABCDE' for y in '1234567']
####列表的生成表达式语法创建列表容器
####已经准备就绪所以需要耗费较多的内存空间
f1 = (x**2 for x in range(1,10))
print(list(f1))
#### 列表生成器 这里得到的不是一个列表 而是一个生成器对象
####通过生成器可以获取到数据 它不占用额外的空间存储数据
####每次需要数据的时候就通过生成器获取数据 当然这需要花费时间
####时间和空间是不可调和的矛盾
####软件和硬件在逻辑上是等效的
from random import randint
def main():
    # 有了列表容器我们可以使用1个变量来保存多个数据
    # 更为重要的是我们可以使用循环对列表中保存的数据进行操作
    f = [0]*11
    for _ in range(60000):
        face = randint(2,12)
        f[face-2] += 1
    for index in range(len(f)):
        print('%d点摇出%d次' %(index+2,f[index]))

   # 直接通过for-in循环对列表(容器)进行遍历
    for counter in f:
        print(counter)
if __name__ == '__main__':
    main()

除了上面提到的生成器语法,Python中还有另外一种定义生成器的方式,就是通过yield关键字将一个普通函数改造成生成器函数。下面的代码演示了如何实现一个生成斐波拉切数列的生成器。所谓斐波拉切数列可以通过下面递归的方法来进行定义:

斐波拉切数列
def main():
     f = [1,1]
     for index in range(2,20):
         val = f[index-1]+f[index-2]
         f.append(val)
     print(f)

 if __name__ == '__main__':
    main()


######生成器函数
def fib(n):
    a,b = 0,1
    for _ in range(n):
        a,b = b,a+b
        yield a

# f = fib(20)
# print(f)

for val in fib(20):
    print(val)
####python内置的排序方法默认都是排升序(从小到大)
#### 如果希望排列成降序(从大到小)可以通过把reverse参数赋为True来指定
####python中的函数几乎都是没有副作用的函数
#####调用函数之后不会影响传入的参数

    f = [1,2,3,4,10,6,7,8,9]
    f2=sorted(f,reverse=True)  #复制了的一个新的列表,不会影响原来的列表
    print(f)
    print(f2)
    f3 = list(reversed(f))
    print(f3)
    print(f)


    f.sort(reverse=True)  #在原来列表的基础上做由大到小的序列改变

    print(f)
    f3 =list( reversed(f)) #新建的一个列表做翻转,没有改变原列表
    print(f3)
    print(f)
    f4 = f3    #没有复制新列表,只是引用了相同的对象
    import sys
    print(sys.getsizeof(f4))
    print(sys.getsizeof(f3))
    print(f3 is f4)    #True

    print(f3)
    print(max(f))
    print(min(f))
    print(float(sum(f)/len(f)))
def main():
    names = ['刘备','张飞','曹操','袁绍','关羽','赵云','周瑜']
    s = []
    for name in names:
        score = input('请输入%s的成绩:' % name)
        s.append(score)
    print(s)
    # s1 = s.sort()
    s1 = sorted(s)
    print(s)
    print(s1)

    a = s.index(s1[6])
    print('得最高分的是:%s' %names[a])
    print(s1[6])
    # print(s1[6])

    # scores = [95, 78, 62, 99, 100, 65, 37]
    # min_score = max_score = scores[0]
    # total = 0
    # for score in scores:
    #     if score > max_score:
    #         max_score = score
    #     elif score < min_score:
    #         min_score = score
    #     total += score
    # print('最高分:', max_score)
    # print('最低分:', min_score)
    # print('平均分:%.1f' % (total / len(scores)))


if __name__ == '__main__':
    main()

f = [‘dysdyete’,’dcfetsgd’,’dfew’,’dfwyedyyefuydd’,’dewyyfe’]
f2 = sorted(f,key=len,reverse=True) #通过引入key关键字,指定列表中字符串的长度来排序而不是默认的字母表顺序
print(f2)

import sys
list1 = [0]*10
list2 = list1
list3 = list2
print(sys.getsizeof(list1))
print(sys.getrefcount(list1))
76
4

import sys
list1 = [0]*10
list2 = list1[:]
list3 = list2[:]
print(sys.getsizeof(list1)) #getsizeof是sys模块中输出列表占用的内存字节大小的
print(sys.getrefcount(list1)) #getrefcount是sys模块中的用于计算对象的引用个数的
76
2

list = [x**2 for x in range(1,10)]
list = list+[20,30]
%timeit(1,2,3,4,5,3,2,1,1,3,4,4,5,)

21.7 ns ± 0.281 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

元组的运行效率比列表的要快得多

%timeit[1,2,3,4,5,3,2,1,1,3,4,4,5,]

179 ns ± 2.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
双色球机选
from random import randint,sample,choices

def display(balls):
    for index,ball in enumerate(balls):#enumerate是枚举的作用
        if index == len(balls) - 1:
            print('|', end=' ')
        print('%02d' % ball, end=' ')
    print()

def random_select():
    red_balls = [x for x in range(1, 34)]
    selected_balls = []
    #第一种写法:
    for _ in range(6):
        index = randint(0, len(red_balls) - 1)
        selected_balls.append(red_balls[index])
        del red_balls[index]
    #第二种写法:
    selected_balls = sample(red_balls,6)#随机采样,无重复数字,所以也可以用这种
    #selects_balls = choices(red_balls,k = 6) 随机采样,有重复数字,所以这里不能用这种方式
    selected_balls.sort()
    selected_balls.append(randint(1, 16))
    return selected_balls

def main():
    n = int(input('机选几注: '))
    for _ in range(n):
        display(random_select())

if __name__ == '__main__':
    main()
取列表里的第二大元素
def Second_large_num(x):
  # 文 档 注 释
    """

    :param num_list: 一个由数字组成的列表
    :return: 列表中的第二大元素
    """
#one是代表最大值的一个变量
#two是代表第二大值的变量
    (one,two) = (x[0],x[1]) if x[0] > x[1] else (x[1],x[0])
    for i in range(2, len(x)):
        if x[i] > one:
            two = one
            one = x[i]
        elif x[i] > two:
            two = x[i]
        else:
            pass
    return two


if __name__ == '__main__':
    num_list = [110, 34, 11, 23, 56, 78, 0, 99, 12, 3, 79, 5]
    print(Second_large_num(num_list))
约瑟夫环问题
def main():
    persons = [True]*30
    counter = 0
    index = 0
    number = 0
    while counter<15:
        if persons[index]:
            number += 1
            if number == 9:
                persons[index] = False
                counter +=1
                number = 0
        index +=1
        index %= 30
    for person in persons:
        print('基督徒' if person else '非基督徒',end = '')

if __name__ == '__main__':
    main()
双重列表的实际应用
def main():
    names = ['关羽','张飞','赵云','马超','曹操']
    subjects = ['语文','数学','python']
    table = []
    for row,name in enumerate(names):
        print('请输入%s的成绩:' % name)
        scores = []
        for col,subject in enumerate(subjects):
            score = int(input('%s:' % subject))
            scores.append(score)
        table.append(scores)
        print(table)

if __name__ == '__main__':
    main()

#table = [[0 for _ in range(3)] for _ in range(5)]
# for row,name in enumerate(names):
#     print('请输入%s的成绩:' % name)
#     for col,subject in enumerate(subjects):
#         score = int(input('%s:' % subject))
#         table[row][col] = score
#     print(table)
def is_leap_year(year):
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0

def which_day(year,month,date):
    days_of_month = [[31,28,31,30,31,30,31,31,30,31,30,31],[31,29,31,30,31,30,31,31,30,31,30,31]][is_leap_year(year)]
    total = 0
    for index in range(month-1):
        total += days_of_month[index]
    return total + date

def main():
    print(which_day(1980,11,28))
    333
    print(which_day(2016,3,1))
    61

if __name__ == '__main__':
    main()
杨辉三角
第一种方法
def triangel(n):
    L=[1]                                                                 #定义一个list[1]
    while True:
        yield L                                                           #打印出该list
       L=[L[x]+L[x+1] for x in range(len(L)-1)] #计算下一行中间的值(除去两边的1)
        L.insert(0,1)                #在开头插入1
        L.append(1)                  #在结尾添加1
        if len(L)>10:                 #仅输出10行
            break
#生成一个generator对象,然后通过for循环迭代输出每一行
a=triangel(10)
for i in a:
    print(i)
第二种方法
def triangles(n):
    L = [1]
    a = 0
    while a <= n:
        a += 1
        yield L
        L.append(0)
        L = [L[i - 1] + L[i] for i in range(len(L))]
for l in triangles(5):
    print(l)



元组

tuple = (1,) 这是元组类型

tuple = (1) 这是整型

tuple = (1,1,2,3,3)
print(tuple[0])
1
元组与列表的差别就是元组内的元素是不可改变的,所以在一些特殊情况下用元组比用列表合适
def main():
# 定义元组
t = (‘熊彪’, 25, True, ‘四川成都’)
print(t)
# 获取元组中的元素
print(t[0])
print(t[3])
# 遍历元组中的值
for member in t:
print(member)
# 重新给元组赋值
# t[0] = ‘王大锤’ # TypeError
# 变量t重新引用了新的元组原来的元组将被垃圾回收
t = (‘王大锤’, 20, True, ‘云南昆明’)
print(t)
# 将元组转换成列表
person = list(t)
print(person)
# 列表是可以修改它的元素的
person[0] = ‘李小龙’
person[1] = 25
print(person)
# 将列表转换成元组
fruits_list = [‘apple’, ‘banana’, ‘orange’]
fruits_tuple = tuple(fruits_list)
print(fruits_tuple)

if name == ‘main‘:
main()

集合

集合里面不能有重复的元素,所以可以对列表,元组进行去重处理。集合跟数学上的集合有一些相似的特点,没有顺序,集合里面元素不可改变,但是可以对它进行遍历
set1 = {1, 2, 3, 3, 3, 2}
 x = sorted(set1,reverse=True)
    print(x)
    [3,2,1]
    print(set1)
    print('Length =', len(set1))
    set2 = set(range(1, 10))
    print(set2)
    set1.add(4)
    print(set1) #{1,2,3,4}
    set1.add((2,3))
    print(set1)  #{1,2,3,4,(2,3)}
    #add 里面不能添加list和dict,因为它们是可变的数据类型,会直接报错
    set3 = {1,2}
    set3.update([3])
    print(set2) #{1,2,3}
    set3.update((True,False))
    集合在做去重处理时把布尔值True当成1,False为0
    print(set3)#{False,1,2,3}
    set3.update(['True'])
    print(set3)  #{'True',1,2,3,False}
    set3.update({'name':'熊彪'})
    print(set3) #{'True',1,2,3,False,'name'}
    #update里面必须加容器,可以是任何容器,然后是把容器里的元素加进集合
    set3.remove(0)
    print(set3) #{'True',1,2,3,'name'}
    # remove的元素如果不存在会引发KeyError
    if 4 in set2:
        set2.remove(4)
    print(set2)
    # 遍历集合容器
    for elem in set2:
        print(elem ** 2, end=' ')
    print()
    # 将元组转换成集合
    set3 = set((1, 2, 3, 3, 2, 1))
    print(set3.pop())
    print(set3)
    # 集合的交集、并集、差集、对称差运算
    print(set1 & set2)
    # print(set1.intersection(set2))
    print(set1 | set2)
    # print(set1.union(set2))
    print(set1 - set2)
    # print(set1.difference(set2))
    print(set1 ^ set2)
    # print(set1.symmetric_difference(set2))
    # 判断子集和超集
    print(set2 <= set1)
    # print(set2.issubset(set1))
    print(set3 <= set1)
    # print(set3.issubset(set1))
    print(set1 >= set2)
    # print(set1.issuperset(set2))
    print(set1 >= set3)
    # print(set1.issuperset(set3))
    x = sorted(set1,reverse=True)
    print(x)
    [3,2,1]

字典

字典里的内容可以做更改,普通的字典是无序的,但可以通过 collections模块把它做成有序字典
def main():
    dict1 = {'name':'熊彪','age':25,'gender':True}
    print(dict1['name'])
    dict1['name'] = '陈晨'
    print((dict1))
    dict1.update(height=170, fav=['看电影','嫖娼'])
    dict1.pop('age')
    print(dict1)
    dict1.popitem()
    dict1['name'] = None
    print(dict1)
    del dict1['gender']
    for x in dict1:
        print(x,'--->',dict1[x])

 if __name__ == '__main__':
    main()

熊彪
{‘name’: ‘陈晨’, ‘age’: 25, ‘gender’: True}
{‘name’: ‘陈晨’, ‘gender’: True, ‘height’: 170, ‘fav’: [‘看电影’, ‘嫖娼’]}
{‘name’: None, ‘gender’: True, ‘height’: 170}
name —> None
height —> 170

dict1 = {'a':1,'b':2}
for k,v in dict1.items():
    #dict1[v] = k
    dict1.setdefault(v,k)
print(dict1)

{1:’a’,2:’b’}

内存管理


栈 堆 静态区
变量–对象的引用–对象的地址–栈
对象–堆–获取更大的存储空间
id() 函数和is运算符是用来验证身份
list1 = [x for x in range(1,10)]
list2 = list1[:]
list1[1] = 300
list2[0] = 100
print(list1 is list2)
False

面向对象

1.定义类

类是对象的蓝图和模板 有了类就可以创建对象
定义类需要做两件事:数据抽象和行为抽象
数据抽象-抽取对象共同的静态特征(找名词)-属性
行为对象-抽取对象共同的动态特征(找动词)-方法
定义类的关键字-class-类名(每个单词首字母大写)

class Student(object):
    def __init__(self,name,age):
    #给对象绑定属性
    #构造方法(构造器-constructor)
    #调用该方法的时候不是直接使用方法的名字而是使用类的名字
        self.name = name
        self.age = age
######我们定义一个方法就代表对象可以接收这个消息
######对象的方法的第一个参数都是写成self
######它代表了接收消息的对象——对象.消息(参数)
    def study(self,course):
        print('%s正在学习%s.' % (self.name,course))

    def watch_av(self):
        if self.age >= 20:
            print('%s正在观看岛国爱情动作片.' %self.name)
        else:
            print('%s,我推荐你看<<熊出没>>.' %self.name)

    def sleep(self):
        print('%s正在睡觉' %self.name)

def main():
### 2

调用构造方法创建学生对象
    #实际调用的是student类中__init__方法
    stu1 = Student('熊彪',25)

##### 3.给对象发出消息
    #通过给对象发消息让对象完成某些工作
    #解决任何问题都是通过让对象去做事情
    stu1.study('python程序设计')
    stu2 = Student('陈晨',18)

    stu2.watch_av()
    stu2.sleep()


if __name__ == '__main__':
    main()
class Rectangle(object):
    def __init__(self,width,height):
        self._height = height
        self._width = width



    def area(self):
        return  self._height * self._width



    def perimeter(self):
        return  (self._height + self._width)*2



def main():
    rectangle1 = Rectangle(10,5)
    print(rectangle1.area())
    print(rectangle1.perimeter())
    rectangle2 = Rectangle(8,4)
    print(rectangle2.area())
    print(rectangle2.perimeter())


if __name__ == '__main__':
    main()
从系统获取时间参数做数字时钟
import  os
from  time import sleep
import  datetime
class Clock(object):
    def __init__(self,hour=datetime.datetime.now().hour,minute=datetime.datetime.now().minute,second=datetime.datetime.now().second):
        self._hour = hour
        self._minute = minute
        self._second = second

    def run(self):
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0

    def show(self):
        return  '%02d:%02d:%02d' %(self._hour,self._minute,self._second)

#下面的方法可以获得对象的字符串表示形式
#当我们用print打印对象时会自动调用该方法
    # def __str__(self):
    #     return  '%02d:%02d:%02d' %(self._hour,self._minute,self._second)

def main():
    time1 = Clock()
    while True:
        os.system('cls')
        print(time1.show())
        sleep(1)
        time1.run()
from math import pi
#我们定义一个类实际上是把数据和操作数据的函数绑定到一起
#形成一个逻辑上的整体 这个整体就叫对象
#而且将来任何时候想使用这种对象时直接复用这个类就可以了
class Circle(object):

    def __init__(self,radius):
        self._radius = radius

    def area(self):
        return  pi*self._radius**2

    def perimeter(self):
        return  2*pi*self._radius

def main():
    r = float(input('请输入游泳池的半径:'))
    big = Circle(r+3)
    small = Circle(r)
    print('围墙的造价为%.2f元' %(big.perimeter()*35.5))
    print('过道的造价为%.2f元' %((big.area()-small.area())*25))


if __name__ == '__main__':
    main()
运算符重写
class Num(object):
    def __init__(self, value):
        if not isinstance(value, int):
            pass
        else:
            self.value = value
    '''
    1.在类内定义了重载方法
    2.在类外进行减法运算时,该方法会被自动调用
    3.在调用时,被减数传递给第一个参数, 减数传递给第二个参数
    '''
    def __sub__(self, num1):
        return self.value * num1
num = Num(13)

y = num - 5
print(y)
65