stay hungry stay foolish

python(高级特性)

切片

类似于js中的slice函数,可以针对数组和字符串进行截取。

>>> arr=[0,1,2,3,4]
>>> arr[0:2]
[0, 1]
>>> arr[:2]
[0, 1]
>>> arr[0:-2]
[0, 1, 2]
>>> arr[0:]
[0, 1, 2, 3, 4]
>>> 'abcd'[0:2]
'ab'
>>>

迭代

python中迭代只有for..in,数组,字符串,dic,set都可以通过for…in来进行迭代。

>>> for x in [1,2,3]:
...  print(x)
...
1
2
3
>>> for ch in [1,2,3]:
...  print(ch)
...
1
2
3
>>> for value in {'a':1,'b':2}.values():
...  print(value)
...
1
2
>>> for key,value in {'a':1,'b':2}.items():
...  print(key,value)
...
a 1
b 2
>>> for x,y in [(1,'a'),(2,'b'),[3,'c']]:#每个数组元素的个数都要为两个,多了或少了都不行
...  print(x,y)
...
1 a
2 b
3 c
>>>

可以用isinstance判断对象是否可迭代。

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

列表生成式

>>> [x*x for x in [1,2,3]]
[1, 4, 9]
>>> [x*x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> [x+y for x in 'abc' for y in 'ABC'] #可以有多个循环
['aA', 'aB', 'aC', 'bA', 'bB', 'bC', 'cA', 'cB', 'cC']
>>> [x+y for x,y in {'a':'A','b':'B'}.items()]
['aA', 'bB']
>>>

生成器(generator)

生成器和列表生产式类似,只不过列表生成式最终保存的时列表,而生成器只是保存了算法,生成器中的每个元素都是通过计算获得的。

普通生成器

语法类似列表生成式,只不过[]换成(),可以不断通过next获取下一个值,最后将抛出StopIteration错误,也可以使用for循环来迭代。不管使用next还是for循环,都只能遍历一次。

>>> g=(x*x for x in [1,2,3])
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> for x in g:
...  print(x)
...
>>>
>>> g=(x*x for x in [1,2,3])
>>> for x in g:
...  print(x)
...
1
4
9

函数生成器

当一个函数里含有yield关键字时,这个函数就变成了一个生成器。

>>> def fab(n):
...  t,a,b = 0,0,1
...  while(t<n):
...   yield b
...   a,b,t = b,a+b,t+1
...  return 'done'
...
>>> for x in fab(5):
...  print(x)
...
1
1
2
3
5
>>> g = fab(5)
>>> while True:
...  try:
...   print(next(g))
...  except StopIteration as e: #函数返回值将挂载到StopIteration错误对象上
...   print(e.value)
...   break
...
1
1
2
3
5
done
>>>

迭代器

list,tuple,str,set,dec,generator都可以被for循环所迭代,因此它们都属于Iterable(可迭代对象)。不过generator比较特殊,它不但属于可迭代对象,同时还属于Iterator(迭代器),python中规定可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

>>> from collections import Iterator
>>> from collections import Iterable
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>>

可以通过iter方法将Iterable对象变成Iterator对象

>>> g = [x*x for x in [1,2,3]]
>>> g = iter(g)
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>>

Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。Python的for循环本质上就是通过不断调用next()函数实现的。