Python的第二周学习总结

day 06

2018.3.5

知识点:

1. 定义函数

  • 我们可以把程序中相对独立的功能模块抽取出来
  • 这样做的好处一是减少重复代码的编写
  • 二是将来可以重复的使用这些功能模块
  • python中的函数就是代表了这样的功能模块
  • y = f(x) f是函数名 x是自变量 y是因变量
def factorial(x):
    #文档注释
    """
    计算阶乘
    :param x: 一个非负整数
    :return: x的阶乘
    """
    y = 1
    for z in range(1, x + 1):
        y *= z
    return y

# 通过下面的if条件可以在导入模块时不去执行下面的代码
if __name__ == '__main__' :
    m = int(input('m = '))
    n = int(input('n = '))
    # 当需要计算阶乘的时候不用再写循环而是直接调用已经定义好的函数
    print(factorial(m) // factorial(n) // factorial(m - n))

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

2. 文档注释

每写一个函数的时候都应加上文档注释,以便增强代码的阅读性,下面以判断一个数是不是回文素数为例来说明文档注释该如何去写
from math import sqrt

def is_prime(num):
    """
    判断一个数是不是素数
    """
    for x in range(2,int(sqrt(num))+1):
        if num % x == 0 :
            return False
    return True if num != 1 else False

def is_paliome(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_paliome(number) and is_prime(number):
        print('%d是回文素数'% number)
    else:
        print('%d不是回文素数'% number)

3. 调用函数的一些注意事项

调用某一个函数的所有方法直接写*就行
from combination import
调用函数的时候可以用as作别名
import combination as com
调用同一命名的函数,后调用的时候覆盖前面调用的
from is_prime import gcd
from math import gcd
每次写执行语句需写上该句话
if _name_ == ‘_main_‘:

4.全局变量和局部变量

下面直接以一个代码来说明全局变量和局部变量

a = 100
# 实际开发时一定要减少对全局变量的使用
# 迪米特法则


#Python搜索一个变量的方式是从局部作用域到嵌套作用于再到全局作用域
# Local - Enclosed - Global
# 如果想改变搜索范围 可以使用global和nonlocal关键字

def foo():
    # 函数内的局部变量 离开foo函数变量a是无法访问的
    # local variable
    global a
    a = 200
    b = 'hello'

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

    bar()
    print(b)

foo()
print(a)

练习题

练习一:拿火柴,谁先拿到21根火柴谁就输,人先拿,计算机后拿,1到4根。保证计算机赢

from random import randint


def main():
    total = 21
    while total > 0:
        print('总共还有%d根火柴'%total)
        while True:
            num = int(input('拿几根火柴:'))
            if 1 <= num <= 4 and num <= total:
                break
        total -= num
        if total > 0:
            com = randint(1, min(4, total))
            total -= com
            print('计算机拿走了%d根火柴'%com)
            if total == 0:
                print('计算机拿到最后一根火柴,你赢了')
        else:
            print('你拿到了最后一根火柴,你输了!')


if __name__ == '__main__':
    main()

练习二:练习一的情景下保证计算机赢

from random import randint
num = 0
while num < 21:
    x = int(input('请输入你要拿的火柴数:'))
    if 1 <= x <= 4 :
        y = randint((5 - x),(5 - x))
        print('电脑拿了%d根火柴'%y)
        num = num + x + y
        print('现在拿到了%d根火柴'%num)
    else:
        print('你拿的火柴数不对,请重新拿')
if num + x >= 21 :
    print('你输了')
elif num + y >= 21:
    print('电脑输了')

练习三:写一个函数判断一个字符串是不是回文字符串

list1 = str(input('输入一个字符串:'))
list2 = []
i = 0
j = len(list1)
if j >= 3:
    while i <= j - 1 :
        list2.append(list1[j-1-i])
        i += 1
    # print(list(list1))
    # print(list2)
    if list2 == list(list1) :
        print('这个字符串是回文字符串')
    else:
        print('这个字符串不是回文字符串')
else:
    print('这个字符串不是回文字符串')

练习四:给两个数,求它们的最大公约数和最小公倍数

#计算最大公约数函数
def gcd(x,y):
     """
     判断素数

     Parameters:
        num: 一个正整数

     Returns:
        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)

day 07

2018.3.6

知识点:

1. 函数的递归调用

①. 收敛条件 - 让递归在有限的次数完成或者进行回溯
如果递归无法在有限次数内收敛就有可能导致RecursionError
②. 递归公式

例如:

# 小孩走10级台阶,一次可能走1级,2级,3级。有多少种走法
def walk(n):
    if n < 0:
        return 0
    elif n == 0:
        return 1
    return walk(n - 1) + walk(n - 2) + walk(n - 3)

# 递归实现1到100求和
def my_sum(n):
    if n == 1:
        return 1
    return n + my_sum(n-1)

#  求最大公约数
def gcd(x,y):
    if x > y :
        return gcd(y,x)
    elif y % x == 0:
        return x
    else:
        return gcd(y % x, x)

# 求n的阶乘
def f(n):
    if n == 0 or n == 1:
        return 1
    return n * f(n - 1)

2. 字符串的使用

通过下面的代码可更加直观的学习到字符串的一些使用

def main():
    str1 = 'hello, world!'
    # 通过len函数计算字符串的长度
    print(len(str1))  # 13
    # 获得字符串首字母大写的拷贝
    print(str1.capitalize())  # Hello, world!
    # 获得字符串变大写后的拷贝
    print(str1.upper())  # HELLO, WORLD!
    # 从字符串中查找子串所在位置
    print(str1.find('or'))  # 8
    print(str1.find('shit'))  # -1
    # 与find类似但找不到子串时会引发异常
    # print(str1.index('or'))
    # 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.isdigit())  # False
    # 检查字符串是否以字母构成
    print(str2.isalpha())  # False
    # 检查字符串是否以数字和字母构成
    print(str2.isalnum())  # True
    str3 = '  [email protected] '
    print(str3)
    # 获得字符串修剪左右两侧空格的拷贝
    print(str3.strip())


if __name__ == '__main__':
    main()

3. 初识栈内存

  • 在进入函数调用之前要保存当前的执行现场
  • 函数的执行现场是保存在一种称为栈(stack)的内存空间上
  • 栈是一种先进后出(FILO)的存储结构

练习题:

练习一:设计函数,产生验证码,指定长度,验证码由大小写字母数字构成

def generate_code(code_len=4):
    """
    生成指定长度的验证码

    :param code_len: 验证码的长度

    :return: 由大小写英文字母数字构成的随机验证码
    """
    all_chars = '0123456789abcdefghijklmnopqlstuvwxyzABCDEFGHIJKLMNOPQLSTUVWXYZ'
    last_pos = len(all_chars) - 1
    code = ''
    for _ in range(code_len):
        index = random.randint(0, last_pos)
        code += all_chars[index]
    return code

练习二:给一个文件名,取出后缀名

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 ''

练习三:设计函数,生成随机文件名

练习四:丢n个色子一万次,统计出现的点数的和的次数

def bar(n):
    from random import randint
    list1 = list()
    for _ in range(10000):
        y = 0
        for _ in range(n):
            y += randint(1,6)
        list1.extend([y])
    for x in range(n, (6 * n + 1)):
        print('丢%d个色子,出现%d的次数为%d次'%(n, x, list1.count(x)))

练习五:跑马灯

def main():
    content = '欢迎来到成都前锋学习......'
    while True:
        os.system('cls')
        print(content)
        time.sleep(0.5)
        content = content[1:] + content[0]

day 08

2017.3.7

知识点:

列表的使用

下面的代码演示了如何定义列表、使用下标访问列表元素以及添加和删除元素的操作。

def main():
    list1 = [1, 3, 5, 7, 100]
    print(list1)
    list2 = ['hello'] * 5
    print(list2)
    # 计算列表长度(元素个数)
    print(len(list1))
    # 下标(索引)运算
    print(list1[0])
    print(list1[4])
    # print(list1[5])  # IndexError: list index out of range
    print(list1[-1])
    print(list1[-3])
    list1[2] = 300
    print(list1)
    # 添加元素
    list1.append(200)
    list1.insert(1, 400)
    list1 += [1000, 2000]
    print(list1)
    print(len(list1))
    # 删除元素
    list1.remove(3)
    if 1234 in list1:
        list1.remove(1234)
    del list1[0]
    print(list1)
    # 清空列表元素
    list1.clear()
    print(list1)


if __name__ == '__main__':
    main()

和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表,代码如下所示。

def main():
    fruits = ['grape', 'apple', 'strawberry', 'waxberry']
    fruits += ['pitaya', 'pear', 'mango']
    # 循环遍历列表元素
    for fruit in fruits:
        print(fruit.title(), end=' ')
    print()
    # 列表切片
    fruits2 = fruits[1:4]
    print(fruits2)
    # fruit3 = fruits  # 没有复制列表只创建了新的引用
    # 可以通过完整切片操作来复制列表
    fruits3 = fruits[:]
    print(fruits3)
    fruits4 = fruits[-3:-1]
    print(fruits4)
    # 可以通过反向切片操作来获得倒转后的列表的拷贝
    fruits5 = fruits[::-1]
    print(fruits5)


if __name__ == '__main__':
    main()

下面的代码实现了对列表的排序操作。

def main():
    list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry']
    list2 = sorted(list1)
    # sorted函数返回列表排序后的拷贝不会修改传入的列表
    # 函数的设计就应该像sorted函数一样尽可能不产生副作用
    list3 = sorted(list1, reverse=True)
    # 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序
    list4 = sorted(list1, key=len)
    print(list1)
    print(list2)
    print(list3)
    print(list4)
    # 给列表对象发出排序消息直接在列表对象上进行排序
    list1.sort(reverse=True)
    print(list1)


if __name__ == '__main__':
    main()

练习题

练习一:设计一个函数计算传入的成绩列表的平均分要求去掉一个最高分和一个最低分

def main():
    scores = [95, 78, 62, 99, 45, 32, 80]
    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('平均分:',total / len(scores))
    y = total - max_score - min_score
    print('去掉一个最高分和最低分的平均分:',y / (len(scores)-2))

练习二:输入学生成绩,找到成绩最高的学生

def main1():
    names =['刘备','张飞', '曹操', '关羽', '赵云']
    score1 = []
    for index, name in enumerate(names):
        while True:
            score = int(input('请输入%s的成绩:'% name))
            if score >= 0 and score <= 100:
                break
        score1.append(score)
    score2 = score1[:]
    for x in range(1,index + 1):
        if score2[0] < score1[x]:
            score2[0] = score1[x]
    for a in range(len(score1)):
        if score1[a] == score2[0]:
            print('%s同学成绩最高,是%s分'%(names[a],score2[0]))

练习三:设计一个函数从传入的列表中找出第二大的元素(只能使用一次循环)

def max2(x):
    m1, m2 = (x[0], x[1]) if x[0] > x[1] else (x[1], x[0])
    for index in range(2, len(x)):
        if x[index] > m1:
            m2 = m1
            m1 = x[index]
        elif x[index] > m2:
            m2 = x[index]
    return m1, m2

练习四:6个红色球(1-33)和1个蓝色球(1-16)

from random import randrange,randint


def dispaly(balls):
    for index, ball in enumerate(balls):
        if index == len(balls) - 1:
            print('∣',end= '')
        print('%02d'% ball,end=' ')
    print()


def random_select():
    red_balls = list(range(1, 34))
    selected_balls = []
    for _ in range(6):
        index = randrange(0, len(red_balls))
        selected_balls.append(red_balls[index])
        del red_balls[index]
    selected_balls.sort()
    selected_balls.append(randint(1,16))
    return selected_balls


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


if __name__ == '__main__':
    main()

day 09

2018.3.8

知识点:

元组的使用

Python 的元组与列表类似,不同之处在于元组的元素不能修改,在前面的代码中我们已经不止一次使用过元组了。顾名思义,我们把多个元素组合到一起就形成了一个元组,所以它和列表一样可以保存多条数据。下面的代码演示了如何定义和使用元组。

def main():
    # 定义元组
    t = ('李元芳', 38, 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()

集合的使用

Python中的集合跟数学上的集合是一致的,不允许有重复元素,而且可以进行交集、并集、差集等运算

def main():
    set1 = {1, 2, 3, 3, 3, 2}
    print(set1)
    print('Length =', len(set1))
    set2 = set(range(1, 10))
    print(set2)
    set1.add(4)
    set1.add(5)
    set2.update([11, 12])
    print(set1)
    print(set2)
    set2.discard(5)
    # 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))


if __name__ == '__main__':
    main()

字典的使用

字典是另一种可变容器模型,类似于我们生活中使用的字典,它可以存储任意类型对象,与列表、集合不同的是,字典的每个元素都是由一个键和一个值组成的“键值对”,键和值通过冒号分开。下面的代码演示了如何定义和使用字典。

def main():
    scores = {'王大锤': 95, '白元芳': 78, '狄仁杰': 82}
    # 通过键可以获取字典中对应的值
    print(scores['王大锤'])
    print(scores['狄仁杰'])
    # 对字典进行遍历(遍历的其实是键再通过键取对应的值)
    for elem in scores:
        print('%s\t--->\t%d' % (elem, scores[elem]))
    # 更新字典中的元素
    scores['白元芳'] = 65
    scores['诸葛王朗'] = 71
    scores.update(冷面=67, 方启鹤=85)
    print(scores)
    if '武则天' in scores:
        print(scores['武则天'])
    print(scores.get('武则天'))
    # get方法也是通过键获取对应的值但是可以设置默认值
    print(scores.get('武则天', 60))
    # 删除字典中的元素
    print(scores.popitem())
    print(scores.popitem())
    print(scores.pop('王大锤', 100))
    # 清空字典
    scores.clear()
    print(scores)


if __name__ == '__main__':
    main()

练习题

练习一:约瑟夫环

def main():
    """
    约瑟夫环
    :return: 
    """
    peoples = [True] * 30
    index = 0
    numbers = 0
    die = 0
    while die < 15:
        if peoples[index]:
            numbers += 1
            if numbers == 9:
                peoples[index] = False
                die += 1
                numbers = 0
        index += 1
        index %= len(peoples)
    for people in peoples:
        print('o' if people else 'x', end='')


if __name__ == '__main__':
    main()

练习二:杨辉三角

def main(n):
    angle = [1] * n
    for row in range(len(angle)):
        angle[row] = [1] * (row + 1)
        for col in range(len(angle[row])):
            if col == 0 or col == row:
                angle[row][col] = 1
            else:
                angle[row][col] = angle[row-1][col-1] + angle[row-1][col]
            print(angle[row][col], end='\t')
        print()


if __name__ == '__main__':
    main(int(input('输入创建杨辉三角的行数:')))

练习三:螺旋矩阵

day 10

2018.3.9

知识点

1. 定义类

如何去定义一个类,以及其相关结构,都在下面的代码中讲出

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


class Student(object):

    # 构造方法(构造器/构造子 - constructor)
    # 调用该方法的时候不是直接使用方法的名字而是使用类的名字
    def __init__(self, name='无名氏', age=18):
        # 给对象绑定属性
        self.name = name
        self.age = age

    # 我们定义一个方法就代表对象可以接受这个消息
    # 对象的方法第一个参数都是统一写成self
    # 它代表了接收消息的对象 - 对象.消息(参数)
    def study(self,course):
        print('%s正在学习%s' % (self.name, course))

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


def main():
    # step 2. 调用构造方法创建学生对象
    # 实际上调用的是student类中 __init__方法
    stu1 = Student('李元芳', 38)
    # step 3. 给对象发出消息
    # 通过给对象发消息让对象完成某些工作
    # 解决任何的问题都是通过让对象去做事情
    stu1.study('python程序设计')
    stu2 = Student('王大锤', 16)
    stu2.study('HTML网页设计')
    stu2.watch_av()
    tri1 = Triangle(3, 4, 5)
    tri1.area()
    tri1.perimeter()


if __name__ == '__main__':
    main()

你可能感兴趣的:(Python学习总结)