Python数据结构
- 容器(container)
- 可迭代对象(iterable)
- 迭代器(iterator)
- 生成器(generator)
- 列表/集合/字典推导式(list,set,dict comprehension)
容器(container)
- Ex.1 assert在列表,集合,元组中的用法
>>> assert 1 in [1,2,3]
>>> assert 1 in {1,2,3}
>>> assert 1 in (1,2,3)- Ex.2 询问元素是否在dict中用key
>>> d={1:'a',2:'b',3:'c'}
>>> assert 1 in d
>>> assert 'a' not in d- Ex.3 询问substring是否在string中
>>> s='Harrdy2018'
>>> assert 'H' in s
>>> assert 'l' not in sstr,list,dict,tuple,generator,set都是可迭代对象
Iterable:可以直接作用于for循环的对象统称为可迭代对像
- Ex.1 可以使用isinstance()判断一个对象是否是Iterable
>>> from collections import Iterable
>>> isinstance('Harrdy2018',Iterable)
True
>>> isinstance('[1,2,3,4]',Iterable)
True
>>> isinstance({'a':1,'b':2},Iterable)
True
>>> isinstance((1,2,3),Iterable)
True
>>> isinstance((x for x in range(10)),Iterable)
True
>>> isinstance({1,2,3},Iterable)
True列表生成式(List Comprehensions)
- Ex.1 生成[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(1,11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]- Ex.2 生成[1x1, 2x2, 3x3, ..., 10x10]
>>> list(i**2 for i in range(1,11))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]- Ex.3 for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方
>>> list(i**2 for i in range(1,11) if i%2==0)
[4, 16, 36, 64, 100]- Ex.4 使用两层循环,可以生成全排列
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']- Ex.5 for循环其实可以同时使用两个甚至多个变量,比如dict.items()可以同时迭代key和value
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k,v in d.items():
print(k,"=",v)
x = A
y = B
z = C- Ex.6 列表生成式也可以使用两个变量来生成list
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k+"="+v for k,v in d.items()]
['x=A', 'y=B', 'z=C']- Ex.7 把一个list中所有的字符串变成小写
>>> L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']生成器(generator)
算法+节约内存
注意区别以下两种情况:
[x for x in range(10)]------>>列表生成式
(x for x in range(10))------>>generator
- Ex.1 斐波拉契数列(Fibonacci)
def fib(N):
n,a,b=0,0,1
while N>n:
a,b=b,a+b
yield a
n=n+1
>>>
>>> f=fib(7)
>>> for item in f:
print(item)
1
1
2
3
5
8
13迭代器(Iterator)
可以被next()函数调用并不断返回下一个值的对象称为迭代器
- Ex.1 使用isinstance()判断一个对象是否是Iterator
>>> from collections import Iterator
>>> isinstance((x for x in range(10)),Iterator)
True- Ex.2 生成器都是Iterator,但list、dict、str...虽然是Iterable,却不是Iterator。
- 把list、dict、str等Iterable变成Iterator可以使用iter()函数
>>> from collections import Iterator
>>> isinstance(iter('Harrdy2018'),Iterator)
True
>>> isinstance(iter([1,2,3]),Iterator)
True
>>> isinstance(iter({'a':1,'b':2}),Iterator)
True
>>> isinstance(iter({1,2,3}),Iterator)
True为什么?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,
直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,
只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
- Ex.3 for循环本质就是通过不断调用next()函数实现的
it=iter([1,2,3,4,5])
while True:
try:
x=next(it)
print(x)
except StopIteration:
break
>>>
1
2
3
4
5- Ex.4 生成无限序列
>>> from itertools import count
>>> counter=count(start=13)
>>> next(counter)
13
>>> next(counter)
14- Ex.5 从一个有限序列中生成无限序列
>>> from itertools import cycle
>>> num=cycle([1,2,3])
>>> next(num)
1
>>> next(num)
2
>>> next(num)
3
>>> next(num)
1- Ex.6 从无限序列中生成有限序列
>>> from itertools import islice
>>> from itertools import cycle
>>> num=cycle([1,2])
>>> limit=islice(num,0,4)
>>> next(limit)
1
>>> next(limit)
2
>>> next(limit)
1
>>> next(limit)
2
>>> next(limit)
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
next(limit)
StopIteration- Ex.7 自定迭代器 斐波拉契数列(Fibonacci)
class Fib:
def __init__(self):
self.prev=0
self.curr=1
def __iter__(self):
#可迭代对象
return self
def __next__(self):
#迭代器
value=self.curr
self.curr=self.curr+self.prev
self.prev=value
return value
>>> f=Fib()
>>> from itertools import islice
>>> list(islice(f,0,10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]