Skip to content

Latest commit

 

History

History
256 lines (241 loc) · 5.57 KB

File metadata and controls

256 lines (241 loc) · 5.57 KB

高级特性


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 s

可迭代对象

str,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]