python学习笔记二--itertools

标准库itertools

学习自雨痕python笔记和python核心编程。


chain连接多个迭代器
>>> it = chain(xrange(3), "abc")
>>> list(it)
[0, 1, 2, 'a', 'b', 'c']

combinations返回指定长度的元素顺序组合序列。
>>> it = combinations("abcd", 2)
>>> list(it)
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
>>> it = combinations(xrange(4), 2)
>>> list(it)
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

combinations_with_replacement 会额外返回同⼀元素的组合。
>>> it = combinations_with_replacement("abcd", 2)
>>> list(it)
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'b'), ('b', 'c'), ('b', 'd'),('c', 'c'), ('c', 'd'), ('d', 'd')]

compress按条件表过滤迭代器元素,其条件可以是任何布尔列表。
>>> it = compress("abcde", [1, 0, 1, 1, 0])
>>> list(it)
['a', 'c', 'd']

count从起点开始,"无限" 循环下去。
>>> for x in count(10, step = 2):
... print x
... if x > 17: break

cycle迭代结束,再从头来过。
>>> for i, x in enumerate(cycle("abc")):
... print x
... if i > 7: break

dropwhile跳过头部符合条件的元素。
>>> it = dropwhile(lambda i: i < 4, [2, 1, 4, 1, 3])
>>> list(it)
[4, 1, 3]

takewhile 则仅保留头部符合条件的元素。
>>> it = takewhile(lambda i: i < 4, [2, 1, 4, 1, 3])
>>> list(it)
[2,1]

groupby将连续出现的相同元素进行分组。
>>> [list(k) for k, g in groupby('AAAABBBCCDAABBCCDD')]
[['A'], ['B'], ['C'], ['D'], ['A'], ['B'], ['C'], ['D']]
>>> [list(g) for k, g in groupby('AAAABBBCCDAABBCCDD')]
[['A', 'A', 'A', 'A'], ['B', 'B', 'B'], ['C', 'C'], ['D'], ['A', 'A'], ['B', 'B'], ['C','C'], ['D', 'D']]

ifilter与内置函数 filter() 类似,仅保留符合条件的元素。
>>> it = ifilter(lambda x: x % 2, xrange(10))
>>> list(it)
[1, 3, 5, 7, 9]

imap与内置函数 map() 类似。
>>> it = imap(lambda x, y: x + y, (2,3,10), (5,2,3))
>>> list(it)
[7, 5, 13]

islice以切片的⽅式从迭代器获取元素。参数一个时为结束;两个时是从开始到结束(小于不等于结束),三个时由开始到结束(第三个为跨越步数)。
>>> it = islice(xrange(10), 3)
>>> list(it)
[0, 1, 2]
>>> it = islice(xrange(10), 3, 5)
>>> list(it)
[3, 4]
>>> it = islice(xrange(10), 3, 9, 2)
>>> list(it)
[3, 5, 7]

izip与内置函数 zip() 类似,多余元素会被抛弃。
>>> it = izip("abc", [1, 2])
>>> list(it)
[('a', 1), ('b', 2)]

izip_longest,保留多余元素,它提供了⼀个补缺参数。
>>> it = izip_longest("abc", [1, 2], fillvalue = 0)
>>> list(it)
[('a', 1), ('b', 2), ('c', 0)]

permutations与 combinations 顺序组合不同,permutations 让每个元素都从头组合一遍。
>>> it = permutations("abc", 2)
>>> list(it)
[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
>>> it = combinations("abc", 2)
>>> list(it)
[('a', 'b'), ('a', 'c'), ('b', 'c')]

product让每个元素都和后⾯的迭代器完整组合一遍。
>>> it = product("abc", [0, 1])
>>> list(it)
[('a', 0), ('a', 1), ('b', 0), ('b', 1), ('c', 0), ('c', 1)]

repeat将⼀个对象重复n次。
>>> it = repeat("a", n)

starmap按顺序处理每组元素。
>>> it = starmap(lambda x, y: x + y, [(1, 2), (10, 20)])
>>> list(it)
[3, 30]

tee复制迭代器。
>>> for it in tee(xrange(5), 3):
... print list(it)
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]

[0, 1, 2, 3, 4]


迭代器

迭代器协议,仅需要 __iter__() 和 next() 两个⽅法。前者返回迭代器对象,后者依次返回数据,直到引发 StopIteration 异常结束。
返回迭代器对象代替 self._data 列表,可避免对象状态被外部修改。或许你会尝试返回 tuple,但这需要复制整个列表,浪费更多的内存。
iter() 很⽅便,但⽆法让迭代中途停止,这需要⾃己动⼿实现迭代器对象。在设计原则上,通常会将迭代器从数据对象中分离出去。因为迭代器需要维持状态,且可能有多个迭代器在同时操控数据,这些不该成为数据对象的负担,⽆端提升了复杂度。


协程 执⾏行流程:
• 创建协程后对象,必须使⽤ send(None) 或 next() 启动。
• 协程在执行 yield result 后让出执⾏绪,等待消息。
• 调⽤方发送 send("a,b") 消息,协程恢复执⾏,将接收到的数据保存到 s,执⾏行后续流程。
• 再次循环到 yeild,协程返回前⾯处理结果,并再次让出执⾏绪。
• 直到关闭或被引发异常。
close() 引发协程 GeneratorExit 异常,使其正常退出。⽽而 throw() 可以引发任何类型的异常,这需要在协程内部捕获。
虽然⽣成器 yield 能轻松实现协程机制,但离真正意义上的⾼并发还有不小的距离。可以考虑使⽤成熟的第三⽅方库,⽐比如 gevent/eventlet,或直接⽤用 greenlet。


改进回调
回调函数是实现异步操作的常⽤手法,只不过代码规模⼀大,看上去就不那么舒服了。好好的逻辑被切分到两个函数⾥里,维护也是个问题。有了 yield,完全可以⽤ blocking style 编写异步调用。
下⾯面是 callback 版本的示例,其中 Framework 调用 logic,在完成某些操作或者接收到信号后,用 callback 返回异步结果。
>>> def framework(logic, callback):
... s = logic()
... print "[FX] logic: ", s
... print "[FX] do something..."
... callback("async:" + s)
>>> def logic():
... s = "mylogic"
... return s
>>> def callback(s):
... print s
>>> framework(logic, callback)
[FX] logic: mylogic
[FX] do something...
async:mylogic
##################用yield改进的blocking style。
>>> def framework(logic):
... try:
... it = logic()
... s = next(it)
... print "[FX] logic: ", s
... print "[FX] do something"
... it.send("async:" + s)
... except StopIteration:
... pass
>>> def logic():
... s = "mylogic"
... r = yield s
... print r
>>> framework(logic)
[FX] logic: mylogic
[FX] do something
async:mylogic


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值