函数高级特性

切片(Slice)

切片是一个针对tuple和list方便地取元素的方法,下面举例说明:

  1. 取出list L中的0到3个元素
1
L[0:3]

当取出元素从第0个开始时,第一个数字可以缺省

1
L[:3]
  1. 取出倒数后三个元素
    在Python中允许使用L[-1]来取出倒数第一个数,因此可以这样倒着取:
1
L[-3:]
  1. 每两个数取一个数
    切片的最后一个数字表示步长,步长为多少就隔几个数字。
1
L[:10:2]

字符串和tuple同样可以这样使用,只不过返回值为对应类型。

迭代(Iteration)

Python的迭代相比c或者Java来说,功能更强大,除了可以迭代list,还可以迭代dict这种无下标的数据类型。
想要知道一个数据能否迭代可以通过一个函数来完成:

1
2
3
from collections.abc import Iterable
L=[1,2,3]
isinstance(L,Iterable)

下面说明dict如何迭代:

1
2
3
4
5
6
7
8
9
10
11
d={'a':1,'b':2,'c':3}
# 迭代key
for key in d:
print(key)
# 迭代value
for value in d.values():
print(value)
# 迭代key和value
for k,v in d.items:
print(k)
print(v)

需要理解的是,这里的key,value,k,v都是for循环中的形参,没有实际意义。也就是说当in d的时候默认就是取key 。当要迭代其他的时候只需要更改in的后面。我猜测这可能与dict的存储方式有关。

多个元素同时迭代在其他list中也是可以实现的:

1
2
3
4
5
l={(1,2),(3,4),(5,6)}
for x in l:
print(x)
for x,y in l:
print(x,y)

列表生成式

一种快捷生成list的方式,一个例子如下:

1
[x * x for x in range(1, 11)]

如果想要筛选生成的值,可以在for后加上if作为筛选条件,注意这里是筛选条件, 因此这里和平时的if else并不是一个东西。

1
[x * x for x in range(1, 11) if x % 2 == 0]

生成器

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

创建generator

  1. 把一个列表生成式的[]改成()
1
g = (x * x for x in range(10))
  1. 包含yield关键字
    当一个函数包含yield关键字时,他就成了一个generator函数。
1
2
3
4
5
6
7
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'

yield在generator函数中起到了一个return的作用,即到yield便返回。 在调用时,使用一个变量接受一个generator对象。

1
f = fib(6)

调用generator获得值

  1. 使用next()函数依次获得下一个返回值
1
next(f)
  1. 使用for循环
1
2
3
g = (x * x for x in range(10))
for n in g:
print(n)

迭代器

区分IterableIterator

Iterable是可迭代的,是直接可用于for循环的。包括dict、list、tuple、set、str、grenerator。
Iterator是迭代器,是直接可用于next()函数的,生成器都是Iterator对象,集合数据类型可以通过iter()获取Interator对象。

for循环的本质

在Python中for循环本质上就是一个不断调用next()的过程。

1
2
3
4
5
6
it=iter([1,2,3,4,5])
while True:
try:
x=next(it)
except StopIteration:
break