原文链接: https://www.liaoxuefeng.com/wiki/1016959663602400 学习采用的是廖雪峰老师的python教程,很精彩详细,收获很大,聊表感谢!
目录
切片——去字符串首尾的空格迭代——迭代查找最大最小值列表生成器——列表中字符串变小写生成器——杨辉三角形对于需要取指定索引范围的操作,Python有特殊的切片(Slice)操作符,能极大地简化操作。
L =list(range(10)) print(L) # 得到从0开始的10个数 print(L[:4]) # 从L[0]开始取4个元素 print(L[2:5]) # 从L[2]开始取3个元素(5-2),得到第3~5个数 print(L[-1]) # 取倒数第一个元素 print(L[-3:]) # 取倒数三个元素 print(L[::2]) # 隔2取数,得偶数 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3] [2, 3, 4] 9 [7, 8, 9] [0, 2, 4, 6, 8]tuple也可以用切片操作,只是操作的结果仍是tuple:
>>> (0, 1, 2, 3, 4, 5)[:3] (0, 1, 2)字符串也可以用切片操作,只是操作结果仍是字符串:
>>> 'ABCDEFG'[:3] 'ABC' >>> 'ABCDEFG'[::2] 'ACEG'练习:利用切片操作,实现一个trim()函数,去除字符串首尾的空格
def trim(s): while s[:1]== ' ': s=s[1:] while s[-1:]== ' ': s=s[:-1] return (s) # 测试: if trim('hello ') != 'hello': print('测试失败!') elif trim(' hello') != 'hello': print('测试失败!') elif trim(' hello ') != 'hello': print('测试失败!') elif trim(' hello world ') != 'hello world': print('测试失败!') elif trim('') != '': print('测试失败!') elif trim(' ') != '': print('测试失败!') else: print('测试成功!')定义:给定一个list或tuple,可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration)。
在Python中,迭代是通过for … in来完成的.
dict迭代 d = {'a': 1, 'b': 2, 'c': 3} for key in d: #默认情况下,dict迭代的是key print (n) for value in d.values(): #迭代value print(value) for k, v in d.items(): #同时迭代key和value print(k,v) D:\Pythonhello\venv\Scripts\python.exe D:/Pythonhello/a.py a b c 1 2 3 a 1 b 2 c 3 Process finished with exit code 0 字符串迭代 >>> for ch in 'ABC': ... print(ch) ... A B C练习:请使用迭代查找一个list中最小和最大值,并返回一个tuple:
def findMinAndMax(L): if len(L)!=0: Max=Min=L[0] for i in L: if Min>i: Min=i if Max<i: Max=i return (Min, Max) else: return (None, None) # 测试 if findMinAndMax([]) != (None, None): print('测试失败!') elif findMinAndMax([7]) != (7, 7): print('测试失败!') elif findMinAndMax([7, 1]) != (1, 7): print('测试失败!') elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9): print('测试失败!') else: print('测试成功!') 测试成功!如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错,使用内建的isinstance函数可以判断一个变量是不是字符串。
练习:通过添加if语句保证列表生成式能正确地执行:
L1 = ['Hello', 'World', 18, 'Apple', None] L2 = [x.lower() for x in L1 if isinstance(x, str)] # 测试: print(L2) if L2 == ['hello', 'world', 'apple']: print('测试通过!') else: print('测试失败!')一边循环一边计算的机制,称为生成器:generator
最简单的就是把一个列表生成式的[]改为(),由此创建一个generator。
>>> L = [x * x for x in range(5)] >>> L [0, 1, 4, 9, 16] >>> g = (x * x for x in range(10)) >>> g <generator object <genexpr> at 0x1022ef630>generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
g = (x * x for x in range(5)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) D:\Pythonhello\venv\Scripts\python.exe D:/Pythonhello/a.py 0 1 4 9 16 Traceback (most recent call last): File "D:/Pythonhello/a.py", line 7, in <module> print(next(g)) StopIteration但实际基本上永远不会调用next(),而是通过for循环来迭代它。
著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, …
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) #改为 yield b a, b = b, a + b #赋值 n = n + 1 return 'done' >>> fib(6) 1 1 2 3 5 8 'done'上面的函数定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
要把fib函数变成generator,只需要把print(b)改为yield b就可以。则结果如下:
>>> f = fib(6) >>> f <generator object fib at 0x104feaaa0>在执行过程中,遇到yield就中断,下次又继续执行
练习: 杨辉三角定义如下:
1 / \ 1 1 / \ / \ 1 2 1 / \ / \ / \ 1 3 3 1把每一行看做一个list,试写一个generator,不断输出下一行的list:
def triangles(): #重点,有难度 L = [1] while True: yield L #中断,输出当前L L = [1] + [L[x]+L[x+1] for x in range(len(L)-1)] + [1] n = 0 #打印 results = [] for t in triangles(): results.append(t) #附加t n = n + 1 if n == 10: break for t in results: print(t) [1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] [1, 5, 10, 10, 5, 1] [1, 6, 15, 20, 15, 6, 1] [1, 7, 21, 35, 35, 21, 7, 1] [1, 8, 28, 56, 70, 56, 28, 8, 1] [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]注意:测试过程中,容易因为代码格式问题报错,如所有while要对齐,if 和 elif 也要对齐,写代码时应尽量保持其工整。