I guess it comes down to a simple choice: get busy living or get busy dying.
1、切片
倒数第一个元素的索引是-1
取后10个数:L[-10:]
2、迭代
- dict: for value in d.values(), for k, v in d.items()
- from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代 - for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
3、列表生成式
list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10][m + n for m in 'ABC' for n in 'XYZ']
import os # 导入os模块
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录success: [x for x in range(1, 11) if x % 2 == 0]
error: [x for x in range(1, 11) if x % 2 == 0 else 0]success: [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
error: [x if x % 2 == 0 for x in range(1, 11)]
4、生成器
一边循环一边计算的机制,称为生成器:generator, generator保存的是算法, 可迭代
g = (x * x for x in range(10))
next(g)g = (x * x for x in range(10))
for n in g:
print(n)
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
>>> def fib(max):
... n, a, b = 0, 0, 1
... while n < max:
... yield b
... a, b = b, a + b
... n = n + 1
... return 'done'
>>> f = fib(6)
>>> for n in fib(6):
... print(n)
但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
5、迭代器
凡是可作用于for循环的对象都是可迭代对象,包括list,set等集合和生成器;
凡是可作用于next()函数的对象都是迭代器,它们表示一个惰性计算的序列,生成器都是迭代器;
集合数据类型如list、dict、str等是可迭代对象但不是迭代器,不过可以通过iter()函数获得一个迭代器对象。
例如:
if __name__ == "__main__":
a = [1, 2, 3]
b = iter(a)
try:
while True:
print(next(b))
except StopIteration as e:
print(e.value)
>>> output:
1
2
3
None
扩展:
Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。这就是list,dict等集合跟生成器的本质区别
参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640