1.Python range()函数
如果你需要一个数值序列,使用内建函数range() 会很方便,它产生等差级数序列。
for i in range(5):
print(i)
2. 经常取指定索引范围的操作,Python提供了切片(Slice)操作符
>>> L=['A','B','C']
>>> L[0:2]
['A', 'B']
>>> L[0:3]
['A', 'B', 'C']
既然Python支持L[-1]
取倒数第一个元素,那么它同样支持倒数切片
>>> L[-3:-1]
['A', 'B']
>>> L[-2:-1]
['B']
切片操作十分有用。我们先创建一个0-99的数列:
>>> L=list(range(100))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
可以通过切片轻松取出某一段数列。比如前10个数:
>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
后10个数:
>>> L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
前10个数,每两个取一个:
>>> L[:10:2]
[0, 2, 4, 6, 8]
tuple(数组)也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
>>> (1,2,3,4,5)[:3]
(1, 2, 3)
在Python中,迭代是通过for ... in
来完成的
>>> d={'a':1,'b':2,'c':3}
>>> for key in d:
... print(key)
...
a
c
b
在dict中,是按照key——value的方式存储的,如果要迭代value,可以用for value in d.values():
>>> d={'a':1,'b':2,'c':3}
>>> for value in d.values():
... print(value)
...
1
3
2
如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
>>> from collections import Iterable
>>> isinstance('abc',Iterable)
True
>>> isinstance([1,2,3],Iterable)
True
>>> isinstance(123,Iterable)
False
同时引用两个变量:
>>> for x,y in [(1,2),(3,4),(5,6)]:
... print(x,y)
...
1 2
3 4
5 6
4.
列表生成式
要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以用list(range(1, 11))
:
>>> list(range(1,11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但如果要生成
[1x1, 2x2, 3x3, ..., 10x10]
怎么做?方法一是循环:
>>> L=[]
>>> for x in range(1,11):
... L.append(x*x)
...
>>>
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
>>> [x*x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表生成式时,把要生成的元素
x * x
放到前面,后面跟
for
循环,就可以把list创建出来:
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>> [x*x for x in range(1,11) if x%2==0]
[4, 16, 36, 64, 100]
运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:
>>> import os#导入os模块,后面会讲这个概念
>>> [d for d in os.listdir('.')]#os.listdir可以列出文件和目录
['.android', '.bash_history', '.comsol', '.gitconfig', '.ssh', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'IntelGraphicsProfiles', 'learngit', 'Links', 'Local Settings', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{f267d143-11ea-11e7-b1a5-825abc7db992}.TM.blf', 'NTUSER.DAT{f267d143-11ea-11e7-b1a5-825abc7db992}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{f267d143-11ea-11e7-b1a5-825abc7db992}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'OneDrive', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'Videos', '「开始」菜单']
列表生成式也可以使用两个变量来生成list:
d={'X':'A','Y':'B','Z':'C'}
>>> [k + '=' + v for k,v in d.items()]
['Y=B', 'Z=C', 'X=A']
最后把一个list中所有的字符串变成小写:
>>> L=['Hello','World','IBM','Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']
使用内建的
isinstance
函数可以判断一个变量是不是字符串:
>>> x='abc'
>>> y=123
>>> isinstance(x,str)
True
>>> isinstance(y,str)
False
练习:如果list中既包含字符串,又包含整数,把其中中所有的字符串变成小写:
>>> L1=['Hwllo','World',18,'Apple',None]
>>> [s.lower() for s in L1 if isinstance(s,str)]
['hwllo', 'world', 'apple']
5.生成器
在Python中,这种一边循环一边计算的机制,称为生成器:generator
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的
[]
改成()
,就创建了一个generator:>>> L=[x*x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g=(x*x for x in range(10))
>>> g
<generator object <genexpr> at 0x000002725E399F10>
创建
L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generator。
如果要一个一个打印出来,可以通过
next()
函数获得generator的下一个返回值:>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
当然,上面这种不断调用
next(g)
实在是太变态了,正确的方法是使用
for
循环,因为generator也是可迭代对象:
>>> g=(x*x for x in range(10))
>>> for s in g:
... print(s)
...
0
1
4
9
16
25
36
49
64
81
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
>>> def fib(max):
... n,a,b=0,0,1 # n=0,a=0,b=0
... while n < max:
... print(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
就可以了:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
这就是定义generator的另一种方法。如果一个函数定义中包含
yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator: