Skip to content

Commit bc3f4ca

Browse files
committed
高级特性
1 parent a586bdf commit bc3f4ca

File tree

5 files changed

+216
-0
lines changed

5 files changed

+216
-0
lines changed

高级特性/generator.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#生成器 generator
2+
3+
#通过列表生成式,我们可以直接创建一个列表,列表容量肯定是有限的,占用很大的存储空间 。在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:
4+
5+
#把一个列表生成式的[]改成(),就创建了一个generator:
6+
7+
L = [x * x for x in range(10)]
8+
L #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
9+
10+
g = (x * x for x in range(10))
11+
g #<generator object <genexpr> at 0x035A9E70>
12+
#通过next()函数获得generator的下一个返回值
13+
14+
for n in g:
15+
print(n)
16+
17+
18+
#著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
19+
def fib(max):
20+
n, a, b = 0, 0, 1
21+
while n < max:
22+
print(b)
23+
a, b = b, a + b
24+
n = n + 1
25+
return 'done'
26+
27+
28+
#从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。 要把fib函数变成generator,只需要把print(b)改为yield b就可以了:
29+
def fib1(max):
30+
n, a, b = 0, 0, 1
31+
while n < max:
32+
yield b
33+
a, b = b, a + b
34+
n = n + 1
35+
return 'done'
36+
37+
38+
#如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
39+
# generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
40+
41+
42+
#定义一个generator,依次返回数字1,3,5:
43+
def odd():
44+
print('step 1')
45+
yield 1
46+
print('step 2')
47+
yield (3)
48+
print('step 3')
49+
yield (5)
50+
51+
52+
o = odd()
53+
next(o)
54+
next(o)
55+
next(o)
56+
57+
"""
58+
>>> next(o)
59+
step 1
60+
1
61+
>>> next(o)
62+
step 2
63+
3
64+
>>> next(o)
65+
step 3
66+
5
67+
"""
68+
69+
for n in fib1(6):
70+
print(n)
71+
72+
73+
# call generator manually: 拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
74+
g = fib1(5)
75+
while 1:
76+
try:
77+
x = next(g)
78+
print('g:', x)
79+
except StopIteration as e:
80+
print('Generator return value:', e.value)
81+
break
82+
83+
#杨辉三角
84+
def triangles(n):
85+
L , index = [1], 0
86+
while index < n:
87+
yield L
88+
L = [1] + [L[i - 1] + L[i] for i in range(1, len(L))] + [1]
89+
index += 1
90+
91+
for x in triangles(5):
92+
print(x)
93+

高级特性/iter.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#直接作用于for循环的数据类型有以下几种:
2+
3+
#一类是集合数据类型,如list、tuple、dict、set、str等;
4+
#一类是generator,包括生成器和带yield的generator function。
5+
#这些可以直接作用于for循环的对象统称为 可迭代对象: Iterable。
6+
#可以使用isinstance()判断一个对象是否是Iterable对象:
7+
8+
from collections.abc import Iterable
9+
isinstance([], Iterable) #True
10+
isinstance({}, Iterable) #True
11+
isinstance('abc', Iterable) #True
12+
isinstance((x for x in range(10)), Iterable) #True
13+
14+
15+
#生成器 可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
16+
#可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
17+
18+
from collections.abc import Iterator
19+
isinstance((x for x in range(10)), Iterator) #True
20+
isinstance([], Iterator) #False
21+
isinstance({}, Iterator) #False
22+
isinstance('abc', Iterator)#False
23+
24+
25+
# 生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
26+
27+
#把list、dict、str等Iterable变成Iterator可以使用iter()函数:
28+
isinstance(iter([]), Iterator) #True
29+
isinstance(iter('abc'), Iterator) #True
30+
31+
#为什么list、dict、str等数据类型不是Iterator?
32+
33+
#这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
34+
35+
#Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

高级特性/iteration.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration
2+
3+
#dict迭代: dict迭代的是key
4+
d = {'a': 1, 'b': 2, 'c': 3}
5+
6+
for k in d:
7+
print(k)
8+
9+
#迭代value
10+
for value in d.values():
11+
print(value)
12+
13+
#同时迭代key和value
14+
for k, v in d.items():
15+
print('%s == %d' % (k, v))
16+
# a == 1
17+
# b == 2
18+
# c == 3
19+
20+
#使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行
21+
#判断一个对象是可迭代对象
22+
23+
#from collections import Iterable 错误 版本问题
24+
25+
from collections.abc import Iterable
26+
27+
isinstance('abc', Iterable) # str是否可迭代 #True
28+
isinstance([1, 2, 3], Iterable) # list是否可迭代
29+
isinstance(123, Iterable) # 整数是否可迭代
30+
31+
#下标循环 enumerate函数可以把一个list变成索引-元素对
32+
33+
for i, value in enumerate(['A', 'B', 'C']):
34+
print(i, value)
35+
36+
# 0 A
37+
# 1 B
38+
# 2 C
39+
40+
for x, y in [(1, 1), (2, 4), (3, 9)]:
41+
print(x,y)
42+
# 1 1
43+
# 2 4
44+
# 3 9

高级特性/list_compre.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式
2+
3+
#生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):
4+
5+
list(range(1, 11)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
6+
7+
#生成[1x1, 2x2, 3x3, ..., 10x10] #把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来
8+
[x * x for x in range(1, 11)] #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
9+
10+
#for循环后面还可以加上if判断,
11+
[x * x for x in range(1, 11) if x % 2 == 0] #[4, 16, 36, 64, 100]
12+
13+
#两层循环,可以生成全排列
14+
[m + n for m in 'ABC'
15+
for n in 'XYZ'] #['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
16+
17+
#for循环其实可以同时使用两个甚至多个变量,
18+
d = {'x': 'A', 'y': 'B', 'z': 'C'}
19+
for k, v in d.items():
20+
print(k, '=', v)
21+
# x = A
22+
# y = B
23+
# z = C
24+
25+
#把一个list中所有的字符串变成小写:
26+
L = ['Hello', 'World', 'IBM', 'Apple']
27+
[s.lower() for s in L] #['hello', 'world', 'ibm', 'apple']

高级特性/slice.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
3+
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
4+
5+
# 取前3个元素 从0开始直到索引3, 0 ,1,2
6+
L[0:3] #['Michael', 'Sarah', 'Tracy']
7+
L[1:3] #['Sarah', 'Tracy'] 从1开始直到索引3
8+
L[-2:] #['Bob', 'Jack']
9+
L[-2:-1] # ['Bob'] 倒数第一个元素的索引是-1
10+
11+
R = list(range(100))
12+
print('R[:10] =', R[:10]) #R[:10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
13+
print('R[-10:] =', R[-10:]) #R[-10:] = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
14+
print('R[10:20] =', R[10:20]) #R[10:20] = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
15+
print('R[:10:2] =', R[:10:2]) #前10个数,每两个取一个: R[:10:2] = [0, 2, 4, 6, 8]
16+
print('R[::5] =', R[::5]) #所有数,每5个取一个: R[::5] = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
17+

0 commit comments

Comments
 (0)