这货很强大, 必须掌握

文档 链接 http://docs.python.org/2/library/itertools.html

pymotw 链接 http://pymotw.com/2/itertools/

基本是基于文档的翻译和补充,相当于翻译了

itertools用于高效循环的迭代函数集合

组成

总体,整体了解

无限迭代器

复制代码代码如下:

  1. 迭代器 参数 结果 例子
  2. count() start, [step] start, start+step, start+2*step, ... count(10) --> 10 11 12 13 14 ...
  3. cycle() p p0, p1, ... plast, p0, p1, ... cycle('ABCD') --> A B C D A B C D ...
  4. repeat() elem [,n] elem, elem, elem, ... endlessly or up to n times repeat(10, 3) --> 10 10 10

  

处理输入序列迭代器

复制代码代码如下:

  1. 迭代器 参数 结果 例子
  2. chain() p, q, ... p0, p1, ... plast, q0, q1, ... chain('ABC', 'DEF') --> A B C D E F
  3. compress() data, selectors (d[0] if s[0]), (d[1] if s[1]), ... compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
  4. dropwhile() pred, seq seq[n], seq[n+1], starting when pred fails dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
  5. groupby() iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v)
  6. ifilter() pred, seq elements of seq where pred(elem) is True ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
  7. ifilterfalse() pred, seq elements of seq where pred(elem) is False ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
  8. islice() seq, [start,] stop [, step] elements from seq[start:stop:step] islice('ABCDEFG', 2, None) --> C D E F G
  9. imap() func, p, q, ... func(p0, q0), func(p1, q1), ... imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
  10. starmap() func, seq func(*seq[0]), func(*seq[1]), ... starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
  11. tee() it, n it1, it2 , ... itn splits one iterator into n
  12. takewhile() pred, seq seq[0], seq[1], until pred fails takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
  13. izip() p, q, ... (p[0], q[0]), (p[1], q[1]), ... izip('ABCD', 'xy') --> Ax By
  14. izip_longest() p, q, ... (p[0], q[0]), (p[1], q[1]), ... izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-

  

组合生成器

复制代码代码如下:
  1. 迭代器 参数 结果
  2. product() p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop
  3. permutations() p[, r] r-length tuples, all possible orderings, no repeated elements
  4. combinations() p, r r-length tuples, in sorted order, no repeated elements
  5. combinations_with_replacement() p, r r-length tuples, in sorted order, with repeated elements
  6. product('ABCD', repeat=2) AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
  7. permutations('ABCD', 2) AB AC AD BA BC BD CA CB CD DA DB DC
  8. combinations('ABCD', 2) AB AC AD BC BD CD
  9. combinations_with_replacement('ABCD', 2) AA AB AC AD BB BC BD CC CD DD

  

第一部分

itertools.count(start=0, step=1)

创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算(注意:此迭代器不支持长整数)

如果超出了sys.maxint,计数器将溢出并继续从-sys.maxint-1开始计算。

定义

复制代码代码如下:
  1. def count(start=0, step=1):
  2. # count(10) --> 10 11 12 13 14 ...
  3. # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
  4. n = start
  5. while True:
  6. yield n
  7. n += step

  

等同于(start + step * i for i in count())

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. for i in izip(count(1), ['a', 'b', 'c']):
  4. print i
  5.  
  6. (1, 'a')
  7. (2, 'b')
  8. (3, 'c')

  

itertools.repeat(object[, times])

创建一个迭代器,重复生成object,times(如果已提供)指定重复计数,如果未提供times,将无止尽返回该对象。

定义

复制代码代码如下:

  1. def repeat(object, times=None):
  2. # repeat(10, 3) --> 10 10 10
  3. if times is None:
  4. while True:
  5. yield object
  6. else:
  7. for i in xrange(times):
  8. yield object

使用

复制代码代码如下:

  1. from itertools import *
  2.  
  3. for i in repeat('over-and-over', 5):
  4. print i
  5.  
  6. over-and-over
  7. over-and-over
  8. over-and-over
  9. over-and-over
  10. over-and-over

  

第二部分
itertools.chain(*iterables)

将多个迭代器作为参数, 但只返回单个迭代器, 它产生所有参数迭代器的内容, 就好像他们是来自于一个单一的序列.

复制代码代码如下:
  1. def chain(*iterables):
  2. # chain('ABC', 'DEF') --> A B C D E F
  3. for it in iterables:
  4. for element in it:
  5. yield element

  

使用

复制代码代码如下:

  1. from itertools import *
  2.  
  3. for i in chain([1, 2, 3], ['a', 'b', 'c']):
  4. print i
  5. 1
  6. 2
  7. 3
  8. a
  9. b
  10. c
  11.  
  12. from itertools import chain, imap
  13. def flatmap(f, items):
  14. return chain.from_iterable(imap(f, items))
  15. >>> list(flatmap(os.listdir, dirs))
  16. >>> ['settings.py', 'wsgi.py', 'templates', 'app.py',
  17. 'templates', 'index.html, 'config.json']

  

itertools.compress(data, selectors)

提供一个选择列表,对原始数据进行筛选

复制代码代码如下:

  1. def compress(data, selectors):
  2. # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
  3. return (d for d, s in izip(data, selectors) if s)
  4. itertools.dropwhile(predicate, iterable)

  

创建一个迭代器,只要函数predicate(item)为True,就丢弃iterable中的项,如果predicate返回False,就会生成iterable中的项和所有后续项。

即:在条件为false之后的第一次, 返回迭代器中剩下来的项.

复制代码代码如下:

  1. def dropwhile(predicate, iterable):
  2. # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
  3. iterable = iter(iterable)
  4. for x in iterable:
  5. if not predicate(x):
  6. yield x
  7. break
  8. for x in iterable:
  9. yield x

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. def should_drop(x):
  4. print 'Testing:', x
  5. return (x<1)
  6.  
  7. for i in dropwhile(should_drop, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
  8. print 'Yielding:', i
  9.  
  10. Testing: -1
  11. Testing: 0
  12. Testing: 1
  13. Yielding: 1
  14. Yielding: 2
  15. Yielding: 3
  16. Yielding: 4
  17. Yielding: 1
  18. Yielding: -2

  

itertools.groupby(iterable[, key])

返回一个产生按照key进行分组后的值集合的迭代器.

如果iterable在多次连续迭代中生成了同一项,则会定义一个组,如果将此函数应用一个分类列表,那么分组将定义该列表中的所有唯一项,key(如果已提供)是一个函数,应用于每一项,如果此函数存在返回值,该值将用于后续项而不是该项本身进行比较,此函数返回的迭代器生成元素(key, group),其中key是分组的键值,group是迭代器,生成组成该组的所有项。

即:按照keyfunc函数对序列每个元素执行后的结果分组(每个分组是一个迭代器), 返回这些分组的迭代器

等价于

复制代码代码如下:
 
  1. class groupby(object):
  2. # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
  3. # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
  4. def __init__(self, iterable, key=None):
  5. if key is None:
  6. key = lambda x: x
  7. self.keyfunc = key
  8. self.it = iter(iterable)
  9. self.tgtkey = self.currkey = self.currvalue = object()
  10. def __iter__(self):
  11. return self
  12. def next(self):
  13. while self.currkey == self.tgtkey:
  14. self.currvalue = next(self.it) # Exit on StopIteration
  15. self.currkey = self.keyfunc(self.currvalue)
  16. self.tgtkey = self.currkey
  17. return (self.currkey, self._grouper(self.tgtkey))
  18. def _grouper(self, tgtkey):
  19. while self.currkey == tgtkey:
  20. yield self.currvalue
  21. self.currvalue = next(self.it) # Exit on StopIteration
  22. self.currkey = self.keyfunc(self.currvalue)

  

应用

复制代码代码如下:
  1. from itertools import groupby
  2. qs = [{'date' : 1},{'date' : 2}]
  3. [(name, list(group)) for name, group in itertools.groupby(qs, lambda p:p['date'])]
  4.  
  5. Out[77]: [(1, [{'date': 1}]), (2, [{'date': 2}])]
  6.  
  7. >>> from itertools import *
  8. >>> a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
  9. >>> for i, k in groupby(a, len):
  10. ... print i, list(k)
  11. ...
  12. 2 ['aa', 'ab']
  13. 3 ['abc', 'bcd']
  14. 5 ['abcde']

  

另一个例子

复制代码代码如下:
  1. from itertools import *
  2. from operator import itemgetter
  3.  
  4. d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
  5. di = sorted(d.iteritems(), key=itemgetter(1))
  6. for k, g in groupby(di, key=itemgetter(1)):
  7. print k, map(itemgetter(0), g)
  8.  
  9. 1 ['a', 'c', 'e']
  10. 2 ['b', 'd', 'f']
  11. 3 ['g']

  

itertools.ifilter(predicate, iterable)

返回的是迭代器类似于针对列表的内置函数 filter() , 它只包括当测试函数返回true时的项. 它不同于 dropwhile()

创建一个迭代器,仅生成iterable中predicate(item)为True的项,如果predicate为None,将返回iterable中所有计算为True的项

对函数func执行返回真的元素的迭代器

复制代码代码如下:
 
  1. def ifilter(predicate, iterable):
  2. # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
  3. if predicate is None:
  4. predicate = bool
  5. for x in iterable:
  6. if predicate(x):
  7. yield x

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. def check_item(x):
  4. print 'Testing:', x
  5. return (x<1)
  6.  
  7. for i in ifilter(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
  8. print 'Yielding:', i
  9.  
  10. Testing: -1
  11. Yielding: -1
  12. Testing: 0
  13. Yielding: 0
  14. Testing: 1
  15. Testing: 2
  16. Testing: 3
  17. Testing: 4
  18. Testing: 1
  19. Testing: -2
  20. Yielding: -2

  

itertools.ifilterfalse(predicate, iterable)

和ifilter(函数相反 , 返回一个包含那些测试函数返回false的项的迭代器)

创建一个迭代器,仅生成iterable中predicate(item)为False的项,如果predicate为None,则返回iterable中所有计算为False的项 对函数func执行返回假的元素的迭代器

复制代码代码如下:
 
  1. def ifilterfalse(predicate, iterable):
  2. # ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
  3. if predicate is None:
  4. predicate = bool
  5. for x in iterable:
  6. if not predicate(x):
  7. yield x

  

使用

复制代码代码如下:
 
  1. from itertools import *
  2.  
  3. def check_item(x):
  4. print 'Testing:', x
  5. return (x<1)
  6.  
  7. for i in ifilterfalse(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
  8. print 'Yielding:', i
  9.  
  10. Testing: -1
  11. Testing: 0
  12. Testing: 1
  13. Yielding: 1
  14. Testing: 2
  15. Yielding: 2
  16. Testing: 3
  17. Yielding: 3
  18. Testing: 4
  19. Yielding: 4
  20. Testing: 1
  21. Yielding: 1
  22. Testing: -2

  

itertools.islice(iterable, stop)

itertools.islice(iterable, start, stop[, step])

返回的迭代器是返回了输入迭代器根据索引来选取的项

创建一个迭代器,生成项的方式类似于切片返回值: iterable[start : stop : step],将跳过前start个项,迭代在stop所指定的位置停止,step指定用于跳过项的步幅。 与切片不同,负值不会用于任何start,stop和step, 如果省略了start,迭代将从0开始,如果省略了step,步幅将采用1.

返回序列seq的从start开始到stop结束的步长为step的元素的迭代器

复制代码代码如下:
 
  1. def islice(iterable, *args):
  2. # islice('ABCDEFG', 2) --> A B
  3. # islice('ABCDEFG', 2, 4) --> C D
  4. # islice('ABCDEFG', 2, None) --> C D E F G
  5. # islice('ABCDEFG', 0, None, 2) --> A C E G
  6. s = slice(*args)
  7. it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
  8. nexti = next(it)
  9. for i, element in enumerate(iterable):
  10. if i == nexti:
  11. yield element
  12. nexti = next(it)

  

使用

复制代码代码如下:
 
  1. from itertools import *
  2.  
  3. print 'Stop at 5:'
  4. for i in islice(count(), 5):
  5. print i
  6.  
  7. print 'Start at 5, Stop at 10:'
  8. for i in islice(count(), 5, 10):
  9. print i
  10.  
  11. print 'By tens to 100:'
  12. for i in islice(count(), 0, 100, 10):
  13. print i
  14.  
  15. Stop at 5:
  16. 0
  17. 1
  18. 2
  19. 3
  20. 4
  21. Start at 5, Stop at 10:
  22. 5
  23. 6
  24. 7
  25. 8
  26. 9
  27. By tens to 100:
  28. 0
  29. 10
  30. 20
  31. 30
  32. 40
  33. 50
  34. 60
  35. 70
  36. 80
  37. 90

  

itertools.imap(function, *iterables)

创建一个迭代器,生成项function(i1, i2, ..., iN),其中i1,i2...iN分别来自迭代器iter1,iter2 ... iterN,如果function为None,则返回(i1, i2, ..., iN)形式的元组,只要提供的一个迭代器不再生成值,迭代就会停止。

即:返回一个迭代器, 它是调用了一个其值在输入迭代器上的函数, 返回结果. 它类似于内置函数 map() , 只是前者在任意输入迭代器结束后就停止(而不是插入None值来补全所有的输入).

返回序列每个元素被func执行后返回值的序列的迭代器

复制代码代码如下:
 
  1. def imap(function, *iterables):
  2. # imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
  3. iterables = map(iter, iterables)
  4. while True:
  5. args = [next(it) for it in iterables]
  6. if function is None:
  7. yield tuple(args)
  8. else:
  9. yield function(*args)

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. print 'Doubles:'
  4. for i in imap(lambda x:2*x, xrange(5)):
  5. print i
  6.  
  7. print 'Multiples:'
  8. for i in imap(lambda x,y:(x, y, x*y), xrange(5), xrange(5,10)):
  9. print '%d * %d = %d' % i
  10.  
  11. Doubles:
  12. 0
  13. 2
  14. 4
  15. 6
  16. 8
  17. Multiples:
  18. 0 * 5 = 0
  19. 1 * 6 = 6
  20. 2 * 7 = 14
  21. 3 * 8 = 24
  22. 4 * 9 = 36

  

itertools.starmap(function, iterable)

创建一个迭代器,生成值func(*item),其中item来自iterable,只有当iterable生成的项适用于这种调用函数的方式时,此函数才有效。

对序列seq的每个元素作为func的参数列表执行, 返回执行结果的迭代器

复制代码代码如下:

  1. def starmap(function, iterable):
  2. # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
  3. for args in iterable:
  4. yield function(*args)

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. values = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]
  4. for i in starmap(lambda x,y:(x, y, x*y), values):
  5. print '%d * %d = %d' % i
  6.  
  7. 0 * 5 = 0
  8. 1 * 6 = 6
  9. 2 * 7 = 14
  10. 3 * 8 = 24
  11. 4 * 9 = 36

  

itertools.tee(iterable[, n=2])

返回一些基于单个原始输入的独立迭代器(默认为2). 它和Unix上的tee工具有点语义相似, 也就是说它们都重复读取输入设备中的值并将值写入到一个命名文件和标准输出中

从iterable创建n个独立的迭代器,创建的迭代器以n元组的形式返回,n的默认值为2,此函数适用于任何可迭代的对象,但是,为了克隆原始迭代器,生成的项会被缓存,并在所有新创建的迭代器中使用,一定要注意,不要在调用tee()之后使用原始迭代器iterable,否则缓存机制可能无法正确工作。

把一个迭代器分为n个迭代器, 返回一个元组.默认是两个

复制代码代码如下:
  1. def tee(iterable, n=2):
  2. it = iter(iterable)
  3. deques = [collections.deque() for i in range(n)]
  4. def gen(mydeque):
  5. while True:
  6. if not mydeque: # when the local deque is empty
  7. newval = next(it) # fetch a new value and
  8. for d in deques: # load it to all the deques
  9. d.append(newval)
  10. yield mydeque.popleft()
  11. return tuple(gen(d) for d in deques)

  

使用

复制代码代码如下:
 
  1. from itertools import *
  2.  
  3. r = islice(count(), 5)
  4. i1, i2 = tee(r)
  5.  
  6. for i in i1:
  7. print 'i1:', i
  8. for i in i2:
  9. print 'i2:', i
  10.  
  11. i1: 0
  12. i1: 1
  13. i1: 2
  14. i1: 3
  15. i1: 4
  16. i2: 0
  17. i2: 1
  18. i2: 2
  19. i2: 3
  20. i2: 4

  

itertools.takewhile(predicate, iterable)

和dropwhile相反

创建一个迭代器,生成iterable中predicate(item)为True的项,只要predicate计算为False,迭代就会立即停止。

即:从序列的头开始, 直到执行函数func失败.

复制代码代码如下:
  1. def takewhile(predicate, iterable):
  2. # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
  3. for x in iterable:
  4. if predicate(x):
  5. yield x
  6. else:
  7. break

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. def should_take(x):
  4. print 'Testing:', x
  5. return (x<2)
  6.  
  7. for i in takewhile(should_take, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
  8. print 'Yielding:', i
  9.  
  10. Testing: -1
  11. Yielding: -1
  12. Testing: 0
  13. Yielding: 0
  14. Testing: 1
  15. Yielding: 1
  16. Testing: 2

  

itertools.izip(*iterables)

返回一个合并了多个迭代器为一个元组的迭代器. 它类似于内置函数zip(), 只是它返回的是一个迭代器而不是一个列表

创建一个迭代器,生成元组(i1, i2, ... iN),其中i1,i2 ... iN 分别来自迭代器iter1,iter2 ... iterN,只要提供的某个迭代器不再生成值,迭代就会停止,此函数生成的值与内置的zip()函数相同。

复制代码代码如下:
  1. izip(iter1, iter2, ... iterN):
  2. 返回:(it1[0],it2 [0], it3[0], ..), (it1[1], it2[1], it3[1], ..)...
  3.  
  4. def izip(*iterables):
  5. # izip('ABCD', 'xy') --> Ax By
  6. iterators = map(iter, iterables)
  7. while iterators:
  8. yield tuple(map(next, iterators))

  

使用

复制代码代码如下:
  1. from itertools import *
  2.  
  3. for i in izip([1, 2, 3], ['a', 'b', 'c']):
  4. print i
  5. (1, 'a')
  6. (2, 'b')
  7. (3, 'c')

  

itertools.izip_longest(*iterables[, fillvalue])

与izip()相同,但是迭代过程会持续到所有输入迭代变量iter1,iter2等都耗尽为止,如果没有使用fillvalue关键字参数指定不同的值,则使用None来填充已经使用的迭代变量的值。

复制代码代码如下:
  1. class ZipExhausted(Exception):
  2. pass
  3.  
  4. def izip_longest(*args, **kwds):
  5. # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
  6. fillvalue = kwds.get('fillvalue')
  7. counter = [len(args) - 1]
  8. def sentinel():
  9. if not counter[0]:
  10. raise ZipExhausted
  11. counter[0] -= 1
  12. yield fillvalue
  13. fillers = repeat(fillvalue)
  14. iterators = [chain(it, sentinel(), fillers) for it in args]
  15. try:
  16. while iterators:
  17. yield tuple(map(next, iterators))
  18. except ZipExhausted:
  19. pass

  

第三部分

itertools.product(*iterables[, repeat])

笛卡尔积

创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔积的元组,repeat是一个关键字参数,指定重复生成序列的次数。

复制代码代码如下:
 
  1. def product(*args, **kwds):
  2. # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
  3. # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
  4. pools = map(tuple, args) * kwds.get('repeat', 1)
  5. result = [[]]
  6. for pool in pools:
  7. result = [x+[y] for x in result for y in pool]
  8. for prod in result:
  9. yield tuple(prod)

  

例子

复制代码代码如下:
  1. import itertools
  2. a = (1, 2, 3)
  3. b = ('A', 'B', 'C')
  4. c = itertools.product(a,b)
  5. for elem in c:
  6. print elem
  7.  
  8. (1, 'A')
  9. (1, 'B')
  10. (1, 'C')
  11. (2, 'A')
  12. (2, 'B')
  13. (2, 'C')
  14. (3, 'A')
  15. (3, 'B')
  16. (3, 'C')

  

itertools.permutations(iterable[, r])

排列

创建一个迭代器,返回iterable中所有长度为r的项目序列,如果省略了r,那么序列的长度与iterable中的项目数量相同: 返回p中任意取r个元素做排列的元组的迭代器

复制代码代码如下:
  1. def permutations(iterable, r=None):
  2. # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
  3. # permutations(range(3)) --> 012 021 102 120 201 210
  4. pool = tuple(iterable)
  5. n = len(pool)
  6. r = n if r is None else r
  7. if r > n:
  8. return
  9. indices = range(n)
  10. cycles = range(n, n-r, -1)
  11. yield tuple(pool[i] for i in indices[:r])
  12. while n:
  13. for i in reversed(range(r)):
  14. cycles[i] -= 1
  15. if cycles[i] == 0:
  16. indices[i:] = indices[i+1:] + indices[i:i+1]
  17. cycles[i] = n - i
  18. else:
  19. j = cycles[i]
  20. indices[i], indices[-j] = indices[-j], indices[i]
  21. yield tuple(pool[i] for i in indices[:r])
  22. break
  23. else:
  24. return
  25. 也可以用product实现
  26.  
  27. def permutations(iterable, r=None):
  28. pool = tuple(iterable)
  29. n = len(pool)
  30. r = n if r is None else r
  31. for indices in product(range(n), repeat=r):
  32. if len(set(indices)) == r:
  33. yield tuple(pool[i] for i in indices)

  

itertools.combinations(iterable, r)

创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序 (不带重复)

复制代码代码如下:
  1. def combinations(iterable, r):
  2. # combinations('ABCD', 2) --> AB AC AD BC BD CD
  3. # combinations(range(4), 3) --> 012 013 023 123
  4. pool = tuple(iterable)
  5. n = len(pool)
  6. if r > n:
  7. return
  8. indices = range(r)
  9. yield tuple(pool[i] for i in indices)
  10. while True:
  11. for i in reversed(range(r)):
  12. if indices[i] != i + n - r:
  13. break
  14. else:
  15. return
  16. indices[i] += 1
  17. for j in range(i+1, r):
  18. indices[j] = indices[j-1] + 1
  19. yield tuple(pool[i] for i in indices)

  

#或者

  1. def combinations(iterable, r):
  2. pool = tuple(iterable)
  3. n = len(pool)
  4. for indices in permutations(range(n), r):
  5. if sorted(indices) == list(indices):
  6. yield tuple(pool[i] for i in indices)

  

itertools.combinations_with_replacement(iterable, r)

创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序 (带重复)

复制代码代码如下:
  1. def combinations_with_replacement(iterable, r):
  2. # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
  3. pool = tuple(iterable)
  4. n = len(pool)
  5. if not n and r:
  6. return
  7. indices = [0] * r
  8. yield tuple(pool[i] for i in indices)
  9. while True:
  10. for i in reversed(range(r)):
  11. if indices[i] != n - 1:
  12. break
  13. else:
  14. return
  15. indices[i:] = [indices[i] + 1] * (r - i)
  16. yield tuple(pool[i] for i in indices)

  

或者

  1. def combinations_with_replacement(iterable, r):
  2. pool = tuple(iterable)
  3. n = len(pool)
  4. for indices in product(range(n), repeat=r):
  5. if sorted(indices) == list(indices):
  6. yield tuple(pool[i] for i in indices)

  

第四部分

扩展

使用现有扩展功能

复制代码代码如下:
 
  1. def take(n, iterable):
  2. "Return first n items of the iterable as a list"
  3. return list(islice(iterable, n))
  4.  
  5. def tabulate(function, start=0):
  6. "Return function(0), function(1), ..."
  7. return imap(function, count(start))
  8.  
  9. def consume(iterator, n):
  10. "Advance the iterator n-steps ahead. If n is none, consume entirely."
  11. # Use functions that consume iterators at C speed.
  12. if n is None:
  13. # feed the entire iterator into a zero-length deque
  14. collections.deque(iterator, maxlen=0)
  15. else:
  16. # advance to the empty slice starting at position n
  17. next(islice(iterator, n, n), None)
  18.  
  19. def nth(iterable, n, default=None):
  20. "Returns the nth item or a default value"
  21. return next(islice(iterable, n, None), default)
  22.  
  23. def quantify(iterable, pred=bool):
  24. "Count how many times the predicate is true"
  25. return sum(imap(pred, iterable))
  26.  
  27. def padnone(iterable):
  28. """Returns the sequence elements and then returns None indefinitely.
  29.  
  30. Useful for emulating the behavior of the built-in map() function.
  31. """
  32. return chain(iterable, repeat(None))
  33.  
  34. def ncycles(iterable, n):
  35. "Returns the sequence elements n times"
  36. return chain.from_iterable(repeat(tuple(iterable), n))
  37.  
  38. def dotproduct(vec1, vec2):
  39. return sum(imap(operator.mul, vec1, vec2))
  40.  
  41. def flatten(listOfLists):
  42. "Flatten one level of nesting"
  43. return chain.from_iterable(listOfLists)
  44.  
  45. def repeatfunc(func, times=None, *args):
  46. """Repeat calls to func with specified arguments.
  47.  
  48. Example: repeatfunc(random.random)
  49. """
  50. if times is None:
  51. return starmap(func, repeat(args))
  52. return starmap(func, repeat(args, times))
  53.  
  54. def pairwise(iterable):
  55. "s -> (s0,s1), (s1,s2), (s2, s3), ..."
  56. a, b = tee(iterable)
  57. next(b, None)
  58. return izip(a, b)
  59.  
  60. def grouper(iterable, n, fillvalue=None):
  61. "Collect data into fixed-length chunks or blocks"
  62. # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
  63. args = [iter(iterable)] * n
  64. return izip_longest(fillvalue=fillvalue, *args)
  65.  
  66. def roundrobin(*iterables):
  67. "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
  68. # Recipe credited to George Sakkis
  69. pending = len(iterables)
  70. nexts = cycle(iter(it).next for it in iterables)
  71. while pending:
  72. try:
  73. for next in nexts:
  74. yield next()
  75. except StopIteration:
  76. pending -= 1
  77. nexts = cycle(islice(nexts, pending))
  78.  
  79. def powerset(iterable):
  80. "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
  81. s = list(iterable)
  82. return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
  83.  
  84. def unique_everseen(iterable, key=None):
  85. "List unique elements, preserving order. Remember all elements ever seen."
  86. # unique_everseen('AAAABBBCCDAABBB') --> A B C D
  87. # unique_everseen('ABBCcAD', str.lower) --> A B C D
  88. seen = set()
  89. seen_add = seen.add
  90. if key is None:
  91. for element in ifilterfalse(seen.__contains__, iterable):
  92. seen_add(element)
  93. yield element
  94. else:
  95. for element in iterable:
  96. k = key(element)
  97. if k not in seen:
  98. seen_add(k)
  99. yield element
  100.  
  101. def unique_justseen(iterable, key=None):
  102. "List unique elements, preserving order. Remember only the element just seen."
  103. # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
  104. # unique_justseen('ABBCcAD', str.lower) --> A B C A D
  105. return imap(next, imap(itemgetter(1), groupby(iterable, key)))
  106.  
  107. def iter_except(func, exception, first=None):
  108. """ Call a function repeatedly until an exception is raised.
  109.  
  110. Converts a call-until-exception interface to an iterator interface.
  111. Like __builtin__.iter(func, sentinel) but uses an exception instead
  112. of a sentinel to end the loop.
  113.  
  114. Examples:
  115. bsddbiter = iter_except(db.next, bsddb.error, db.first)
  116. heapiter = iter_except(functools.partial(heappop, h), IndexError)
  117. dictiter = iter_except(d.popitem, KeyError)
  118. dequeiter = iter_except(d.popleft, IndexError)
  119. queueiter = iter_except(q.get_nowait, Queue.Empty)
  120. setiter = iter_except(s.pop, KeyError)
  121.  
  122. """
  123. try:
  124. if first is not None:
  125. yield first()
  126. while 1:
  127. yield func()
  128. except exception:
  129. pass
  130.  
  131. def random_product(*args, **kwds):
  132. "Random selection from itertools.product(*args, **kwds)"
  133. pools = map(tuple, args) * kwds.get('repeat', 1)
  134. return tuple(random.choice(pool) for pool in pools)
  135.  
  136. def random_permutation(iterable, r=None):
  137. "Random selection from itertools.permutations(iterable, r)"
  138. pool = tuple(iterable)
  139. r = len(pool) if r is None else r
  140. return tuple(random.sample(pool, r))
  141.  
  142. def random_combination(iterable, r):
  143. "Random selection from itertools.combinations(iterable, r)"
  144. pool = tuple(iterable)
  145. n = len(pool)
  146. indices = sorted(random.sample(xrange(n), r))
  147. return tuple(pool[i] for i in indices)
  148.  
  149. def random_combination_with_replacement(iterable, r):
  150. "Random selection from itertools.combinations_with_replacement(iterable, r)"
  151. pool = tuple(iterable)
  152. n = len(pool)
  153. indices = sorted(random.randrange(n) for i in xrange(r))
  154. return tuple(pool[i] for i in indices)
  155.  
  156. def tee_lookahead(t, i):
  157. """Inspect the i-th upcomping value from a tee object
  158. while leaving the tee object at its current position.
  159.  
  160. Raise an IndexError if the underlying iterator doesn't
  161. have enough values.
  162.  
  163. """
  164. for value in islice(t.__copy__(), i, None):
  165. return value
  166. raise IndexError(i)

  

自定义扩展

将序列按大小切分,更好的性能

复制代码代码如下:
 
  1. from itertools import chain, islice
  2. def chunks(iterable, size, format=iter):
  3. it = iter(iterable)
  4. while True:
  5. yield format(chain((it.next(),), islice(it, size - 1)))
  6.  
  7. >>> l = ["a", "b", "c", "d", "e", "f", "g"]
  8. >>> for chunk in chunks(l, 3, tuple):...
  9. print chunk...
  10. ("a", "b", "c")
  11. ("d", "e", "f")
  12. ("g",)

  

补充

迭代工具,你最好的朋友

迭代工具模块包含了操做指定的函数用于操作迭代器。想复制一个迭代器出来?链接两个迭代器?以one liner(这里的one-liner只需一行代码能搞定的任务)用内嵌的列表组合一组值?不使用list创建Map/Zip?···,你要做的就是 import itertools,举个例子吧:

四匹马赛跑到达终点排名的所有可能性:

复制代码代码如下:

  1. >>> horses = [1, 2, 3, 4]
  2. >>> races = itertools.permutations(horses)
  3. >>> print(races)
  4. <itertools.permutations object at 0xb754f1dc]]>
  5. >>> print(list(itertools.permutations(horses)))
  6. [(1, 2, 3, 4),
  7. (1, 2, 4, 3),
  8. (1, 3, 2, 4),
  9. (1, 3, 4, 2),
  10. (1, 4, 2, 3),
  11. (1, 4, 3, 2),
  12. (2, 1, 3, 4),
  13. (2, 1, 4, 3),
  14. (2, 3, 1, 4),
  15. (2, 3, 4, 1),
  16. (2, 4, 1, 3),
  17. (2, 4, 3, 1),
  18. (3, 1, 2, 4),
  19. (3, 1, 4, 2),
  20. (3, 2, 1, 4),
  21. (3, 2, 4, 1),
  22. (3, 4, 1, 2),
  23. (3, 4, 2, 1),
  24. (4, 1, 2, 3),
  25. (4, 1, 3, 2),
  26. (4, 2, 1, 3),
  27. (4, 2, 3, 1),
  28. (4, 3, 1, 2),
  29. (4, 3, 2, 1)]

  

理解迭代的内部机制: 迭代(iteration)就是对可迭代对象(iterables,实现了__iter__()方法)和迭代器(iterators,实现了__next__()方法)的一个操作过程。可迭代对象是任何可返回一个迭代器的对象,迭代器是应用在迭代对象中迭代的对象,换一种方式说的话就是:iterable对象的__iter__()方法可以返回iterator对象,iterator通过调用next()方法获取其中的每一个值(译者注),读者可以结合Java API中的 Iterable接口和Iterator接口进行类比。

Python itertools模块详解的更多相关文章

  1. [转载] Python itertools模块详解

    原文在这里,写的很详细,感谢原作者,以下摘录要点. itertools用于高效循环的迭代函数集合. 无限迭代器 迭代器 参数 结果 例子 count() start, [step] start, st ...

  2. (转)python collections模块详解

    python collections模块详解 原文:http://www.cnblogs.com/dahu-daqing/p/7040490.html 1.模块简介 collections包含了一些特 ...

  3. python time模块详解

    python time模块详解 转自:http://blog.csdn.net/kiki113/article/details/4033017 python 的内嵌time模板翻译及说明  一.简介 ...

  4. python docopt模块详解

    python docopt模块详解 docopt 本质上是在 Python 中引入了一种针对命令行参数的形式语言,在代码的最开头使用 """ ""&q ...

  5. python pathlib模块详解

    python pathlib模块详解    

  6. Python Fabric模块详解

    Python Fabric模块详解 什么是Fabric? 简单介绍一下: ​ Fabric是一个Python的库和命令行工具,用来提高基于SSH的应用部署和系统管理效率. 再具体点介绍一下,Fabri ...

  7. python time 模块详解

    Python中time模块详解 发表于2011年5月5日 12:58 a.m.    位于分类我爱Python 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括: ...

  8. python常用模块详解

    python常用模块详解 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用p ...

  9. python os模块详解

    一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...

随机推荐

  1. 【mysql】datetime时间比较

    如下,比较的日期用指定格式写出就可以了.不需要日期函数. SELECT * FROM table_a WHERE write_date > "2017-07-17 00:00:00&q ...

  2. Linux基础一:Linux的安装及相关配置

    1. 计算机操作系统简介    1) 操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间.    2) 操作系统的内核的定义:操作系统的内核是一 ...

  3. spring cloud 声明式rest客户端feign调用远程http服务

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...

  4. Html页面添加百度地图

    1.进入百度地图开放平台 http://lbsyun.baidu.com/ 2.进入右上角的   “API控制台” 在这里创建应用 并 获取密钥 3.进入 如下地址 创建地图 http://api.m ...

  5. Python os.walk() 方法遍历文件目录

    概述 os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下. os.walk() 方法是一个简单易用的文件.目录遍历器,可以帮助我们高效的处理文件.目录方面的事情. 在Un ...

  6. Caused by: java.lang.NumberFormatException: For input string: "18446744073709551615"

    问题:Caused by: java.lang.NumberFormatException: For input string: "18446744073709551615" 原因 ...

  7. JavaScript中this 详解

    涵义 this 关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先, this 总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. this.p ...

  8. mysql恢复ibd文件

    1.将原表删除,包括ibd和frm文件 2.重新创建表结构. 3.丢弃表空间 alter table tableName discard tablespace; 4.将要恢复的ibd文件拷贝到数据库目 ...

  9. js 2017

    JS面向对象 <script> function num(val) { return val * 8 } function Index(name, age) { this.name = n ...

  10. springboot学习(一):创建项目

    package com.glory.demo.Controller; import org.springframework.stereotype.Controller; import org.spri ...