Python 高级特性(二)

在Python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。

1
2
3
4
5
L = []
n = 1
while n <= 99:
L.append(n)
n = n + 2

一行代码

1
print(range(1,100,2))

切片

获取数组的子集

1
2
3
4
5
6
7
>>> r = []
>>> n = 3
>>> for i in range(n):
... r.append(L[i])
...
>>> r
['Michael', 'Sarah', 'Tracy']

一行代码写法

1
2
3
4
5
>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
>>> L[0:3]
['Michael','Sarah','Tracy']
>>> L[:3] #省略0 同上
['Michael','Sarah','Tracy']

倒数第一个元素的索引是-1。

1
2
3
4
5
6
#取后10个数
>>> L = list(range(100))
>>> L
range(0,100)
>>> L[-10:]
range(90,100)

前10个数,每两个取一个

1
2
3
4
5
# -*- coding:utf-8 -*-
l = range(0,100)
list = l[0:10:2]
print(list)
# range(0,10,2)

原样复制一个list

1
2
>>> L[:]
range(0,100)

字符串也能看成是list

1
2
3
4
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

迭代

在Python中,迭代是通过for … in来完成的。

1
2
3
4
5
6
7
8
9
10
# -*- coding:utf-8 -*-
d = {'Tim':100,'Gim':88,'Dim':60}
for key in d:
print(key)
for value in d.values():
print(value)
for k,v in d.items():
print('key=%s , value =%s' %(k,v) )

迭代字符串

1
2
3
4
5
>>> for ch in 'ABC':
print(ch)
A
B
C

同时引入2个变量

1
2
3
4
5
6
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
1 1
2 4
3 9

判断对象是否可以迭代

1
2
3
4
5
6
7
8
# -*- coding:utf-8 -*-
from collections import Iterable
foo = isinstance('abc', Iterable) # str是否可迭代
print(foo)
foo = isinstance([1,2,3], Iterable) # list是否可迭代
print(foo)
foo = isinstance(123, Iterable) # 整数是否可迭代
print(foo)

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

1
2
3
# -*- coding:utf-8 -*-
for i, value in enumerate(['A','B','C']):
print(i,value)

列表生成式

1
2
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1
2
3
4
5
# -*- coding:utf-8 -*-
L = []
for i in range(1,11):
L.append(i*i)
print(L)

列表生成式写法

1
2
[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

带if的列表生成式

1
2
3
# -*- coding:utf-8 -*-
L = [x*x for x in range(1,11) if x % 2 == 0]
print(L)

双层循环

1
2
L = [n+m for m in 'ABC' for n in 'XYZ']
print(L)

列出当前目录下的所有文件和目录名

1
2
3
>>> import os # 导入os模块,模块的概念后面讲到
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']

同时使用2个变量

1
2
3
4
d = {'x': 'A', 'y': 'B', 'z': 'C' }
L = [k + '=' + v for k,v in d.items()]
print(L)
['x=A', 'y=B', 'z=C']

转换成小写list

1
2
3
d = ['Hello','World',18,'Apple',None]
L = [str(s).lower() for s in d]
print(L)

作业

1
2
3
4
5
6
# -*- coding:utf-8 -*-
d = ['Hello','World',18,'Apple',None]
#L = [str(s).lower() for s in d]
L = [s for s in d if( isinstance(s,str) )]
#L = isinstance('555',str)
print(L)

生成器 generator

如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

1
2
3
4
5
6
g = ( x * x for x in range(0,10) )
print(next(g))
print(next(g))
print(next(g))
for n in g:
print(n)

斐波那契数

1
2
3
4
5
6
7
8
9
10
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
l = fib(3)
print(l)

yield

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding:utf-8 -*-
def fib(max):
n,a,b = 0,0,1
while n < max:
yield b
a , b = b , a + b
n = n + 1
return 'done'
l = fib(10)
print('l = ', l)
print('next(l) = ', next(l))
print('next(l) = ', next(l))
for x in l:
print(x)

简单的generator写法

1
2
3
4
5
6
7
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)

要获取generator return 的 返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def fib(max):
n,a,b = 0,0,1
while n < max:
yield b
a , b = b , a + b
n = n + 1
return 'done'
g = fib(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break

迭代器

可以使用isinstance()判断一个对象是否是Iterable对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

iter()转换函数

1
2
3
4
5
>>> from collections import Iterable
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True