Python itertools模块详解
这货很强大, 必须掌握
文档 链接 http://docs.python.org/2/library/itertools.html
pymotw 链接 http://pymotw.com/2/itertools/
基本是基于文档的翻译和补充,相当于翻译了
itertools用于高效循环的迭代函数集合
组成
总体,整体了解
无限迭代器
- 迭代器 参数 结果 例子
- count() start, [step] start, start+step, start+2*step, ... count(10) --> 10 11 12 13 14 ...
- cycle() p p0, p1, ... plast, p0, p1, ... cycle('ABCD') --> A B C D A B C D ...
- repeat() elem [,n] elem, elem, elem, ... endlessly or up to n times repeat(10, 3) --> 10 10 10
处理输入序列迭代器
- 迭代器 参数 结果 例子
- chain() p, q, ... p0, p1, ... plast, q0, q1, ... chain('ABC', 'DEF') --> A B C D E F
- 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
- 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
- groupby() iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v)
- ifilter() pred, seq elements of seq where pred(elem) is True ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
- ifilterfalse() pred, seq elements of seq where pred(elem) is False ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
- islice() seq, [start,] stop [, step] elements from seq[start:stop:step] islice('ABCDEFG', 2, None) --> C D E F G
- imap() func, p, q, ... func(p0, q0), func(p1, q1), ... imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
- starmap() func, seq func(*seq[0]), func(*seq[1]), ... starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
- tee() it, n it1, it2 , ... itn splits one iterator into n
- takewhile() pred, seq seq[0], seq[1], until pred fails takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
- izip() p, q, ... (p[0], q[0]), (p[1], q[1]), ... izip('ABCD', 'xy') --> Ax By
- izip_longest() p, q, ... (p[0], q[0]), (p[1], q[1]), ... izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
组合生成器
- 迭代器 参数 结果
- product() p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop
- permutations() p[, r] r-length tuples, all possible orderings, no repeated elements
- combinations() p, r r-length tuples, in sorted order, no repeated elements
- combinations_with_replacement() p, r r-length tuples, in sorted order, with repeated elements
- product('ABCD', repeat=2) AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
- permutations('ABCD', 2) AB AC AD BA BC BD CA CB CD DA DB DC
- combinations('ABCD', 2) AB AC AD BC BD CD
- 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开始计算。
定义
- def count(start=0, step=1):
- # count(10) --> 10 11 12 13 14 ...
- # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
- n = start
- while True:
- yield n
- n += step
等同于(start + step * i for i in count())
使用
- from itertools import *
- for i in izip(count(1), ['a', 'b', 'c']):
- print i
- (1, 'a')
- (2, 'b')
- (3, 'c')
itertools.repeat(object[, times])
创建一个迭代器,重复生成object,times(如果已提供)指定重复计数,如果未提供times,将无止尽返回该对象。
定义
- def repeat(object, times=None):
- # repeat(10, 3) --> 10 10 10
- if times is None:
- while True:
- yield object
- else:
- for i in xrange(times):
- yield object
使用
- from itertools import *
- for i in repeat('over-and-over', 5):
- print i
- over-and-over
- over-and-over
- over-and-over
- over-and-over
- over-and-over
第二部分
itertools.chain(*iterables)
将多个迭代器作为参数, 但只返回单个迭代器, 它产生所有参数迭代器的内容, 就好像他们是来自于一个单一的序列.
- def chain(*iterables):
- # chain('ABC', 'DEF') --> A B C D E F
- for it in iterables:
- for element in it:
- yield element
使用
- from itertools import *
- for i in chain([1, 2, 3], ['a', 'b', 'c']):
- print i
- 1
- 2
- 3
- a
- b
- c
- from itertools import chain, imap
- def flatmap(f, items):
- return chain.from_iterable(imap(f, items))
- >>> list(flatmap(os.listdir, dirs))
- >>> ['settings.py', 'wsgi.py', 'templates', 'app.py',
- 'templates', 'index.html, 'config.json']
itertools.compress(data, selectors)
提供一个选择列表,对原始数据进行筛选
- def compress(data, selectors):
- # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
- return (d for d, s in izip(data, selectors) if s)
- itertools.dropwhile(predicate, iterable)
创建一个迭代器,只要函数predicate(item)为True,就丢弃iterable中的项,如果predicate返回False,就会生成iterable中的项和所有后续项。
即:在条件为false之后的第一次, 返回迭代器中剩下来的项.
- def dropwhile(predicate, iterable):
- # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
- iterable = iter(iterable)
- for x in iterable:
- if not predicate(x):
- yield x
- break
- for x in iterable:
- yield x
使用
- from itertools import *
- def should_drop(x):
- print 'Testing:', x
- return (x<1)
- for i in dropwhile(should_drop, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
- print 'Yielding:', i
- Testing: -1
- Testing: 0
- Testing: 1
- Yielding: 1
- Yielding: 2
- Yielding: 3
- Yielding: 4
- Yielding: 1
- Yielding: -2
itertools.groupby(iterable[, key])
返回一个产生按照key进行分组后的值集合的迭代器.
如果iterable在多次连续迭代中生成了同一项,则会定义一个组,如果将此函数应用一个分类列表,那么分组将定义该列表中的所有唯一项,key(如果已提供)是一个函数,应用于每一项,如果此函数存在返回值,该值将用于后续项而不是该项本身进行比较,此函数返回的迭代器生成元素(key, group),其中key是分组的键值,group是迭代器,生成组成该组的所有项。
即:按照keyfunc函数对序列每个元素执行后的结果分组(每个分组是一个迭代器), 返回这些分组的迭代器
等价于
- class groupby(object):
- # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
- # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
- def __init__(self, iterable, key=None):
- if key is None:
- key = lambda x: x
- self.keyfunc = key
- self.it = iter(iterable)
- self.tgtkey = self.currkey = self.currvalue = object()
- def __iter__(self):
- return self
- def next(self):
- while self.currkey == self.tgtkey:
- self.currvalue = next(self.it) # Exit on StopIteration
- self.currkey = self.keyfunc(self.currvalue)
- self.tgtkey = self.currkey
- return (self.currkey, self._grouper(self.tgtkey))
- def _grouper(self, tgtkey):
- while self.currkey == tgtkey:
- yield self.currvalue
- self.currvalue = next(self.it) # Exit on StopIteration
- self.currkey = self.keyfunc(self.currvalue)
应用
- from itertools import groupby
- qs = [{'date' : 1},{'date' : 2}]
- [(name, list(group)) for name, group in itertools.groupby(qs, lambda p:p['date'])]
- Out[77]: [(1, [{'date': 1}]), (2, [{'date': 2}])]
- >>> from itertools import *
- >>> a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
- >>> for i, k in groupby(a, len):
- ... print i, list(k)
- ...
- 2 ['aa', 'ab']
- 3 ['abc', 'bcd']
- 5 ['abcde']
另一个例子
- from itertools import *
- from operator import itemgetter
- d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
- di = sorted(d.iteritems(), key=itemgetter(1))
- for k, g in groupby(di, key=itemgetter(1)):
- print k, map(itemgetter(0), g)
- 1 ['a', 'c', 'e']
- 2 ['b', 'd', 'f']
- 3 ['g']
itertools.ifilter(predicate, iterable)
返回的是迭代器类似于针对列表的内置函数 filter() , 它只包括当测试函数返回true时的项. 它不同于 dropwhile()
创建一个迭代器,仅生成iterable中predicate(item)为True的项,如果predicate为None,将返回iterable中所有计算为True的项
对函数func执行返回真的元素的迭代器
- def ifilter(predicate, iterable):
- # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
- if predicate is None:
- predicate = bool
- for x in iterable:
- if predicate(x):
- yield x
使用
- from itertools import *
- def check_item(x):
- print 'Testing:', x
- return (x<1)
- for i in ifilter(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
- print 'Yielding:', i
- Testing: -1
- Yielding: -1
- Testing: 0
- Yielding: 0
- Testing: 1
- Testing: 2
- Testing: 3
- Testing: 4
- Testing: 1
- Testing: -2
- Yielding: -2
itertools.ifilterfalse(predicate, iterable)
和ifilter(函数相反 , 返回一个包含那些测试函数返回false的项的迭代器)
创建一个迭代器,仅生成iterable中predicate(item)为False的项,如果predicate为None,则返回iterable中所有计算为False的项 对函数func执行返回假的元素的迭代器
- def ifilterfalse(predicate, iterable):
- # ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
- if predicate is None:
- predicate = bool
- for x in iterable:
- if not predicate(x):
- yield x
使用
- from itertools import *
- def check_item(x):
- print 'Testing:', x
- return (x<1)
- for i in ifilterfalse(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
- print 'Yielding:', i
- Testing: -1
- Testing: 0
- Testing: 1
- Yielding: 1
- Testing: 2
- Yielding: 2
- Testing: 3
- Yielding: 3
- Testing: 4
- Yielding: 4
- Testing: 1
- Yielding: 1
- 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的元素的迭代器
- def islice(iterable, *args):
- # islice('ABCDEFG', 2) --> A B
- # islice('ABCDEFG', 2, 4) --> C D
- # islice('ABCDEFG', 2, None) --> C D E F G
- # islice('ABCDEFG', 0, None, 2) --> A C E G
- s = slice(*args)
- it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
- nexti = next(it)
- for i, element in enumerate(iterable):
- if i == nexti:
- yield element
- nexti = next(it)
使用
- from itertools import *
- print 'Stop at 5:'
- for i in islice(count(), 5):
- print i
- print 'Start at 5, Stop at 10:'
- for i in islice(count(), 5, 10):
- print i
- print 'By tens to 100:'
- for i in islice(count(), 0, 100, 10):
- print i
- Stop at 5:
- 0
- 1
- 2
- 3
- 4
- Start at 5, Stop at 10:
- 5
- 6
- 7
- 8
- 9
- By tens to 100:
- 0
- 10
- 20
- 30
- 40
- 50
- 60
- 70
- 80
- 90
itertools.imap(function, *iterables)
创建一个迭代器,生成项function(i1, i2, ..., iN),其中i1,i2...iN分别来自迭代器iter1,iter2 ... iterN,如果function为None,则返回(i1, i2, ..., iN)形式的元组,只要提供的一个迭代器不再生成值,迭代就会停止。
即:返回一个迭代器, 它是调用了一个其值在输入迭代器上的函数, 返回结果. 它类似于内置函数 map() , 只是前者在任意输入迭代器结束后就停止(而不是插入None值来补全所有的输入).
返回序列每个元素被func执行后返回值的序列的迭代器
- def imap(function, *iterables):
- # imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
- iterables = map(iter, iterables)
- while True:
- args = [next(it) for it in iterables]
- if function is None:
- yield tuple(args)
- else:
- yield function(*args)
使用
- from itertools import *
- print 'Doubles:'
- for i in imap(lambda x:2*x, xrange(5)):
- print i
- print 'Multiples:'
- for i in imap(lambda x,y:(x, y, x*y), xrange(5), xrange(5,10)):
- print '%d * %d = %d' % i
- Doubles:
- 0
- 2
- 4
- 6
- 8
- Multiples:
- 0 * 5 = 0
- 1 * 6 = 6
- 2 * 7 = 14
- 3 * 8 = 24
- 4 * 9 = 36
itertools.starmap(function, iterable)
创建一个迭代器,生成值func(*item),其中item来自iterable,只有当iterable生成的项适用于这种调用函数的方式时,此函数才有效。
对序列seq的每个元素作为func的参数列表执行, 返回执行结果的迭代器
- def starmap(function, iterable):
- # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
- for args in iterable:
- yield function(*args)
使用
- from itertools import *
- values = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]
- for i in starmap(lambda x,y:(x, y, x*y), values):
- print '%d * %d = %d' % i
- 0 * 5 = 0
- 1 * 6 = 6
- 2 * 7 = 14
- 3 * 8 = 24
- 4 * 9 = 36
itertools.tee(iterable[, n=2])
返回一些基于单个原始输入的独立迭代器(默认为2). 它和Unix上的tee工具有点语义相似, 也就是说它们都重复读取输入设备中的值并将值写入到一个命名文件和标准输出中
从iterable创建n个独立的迭代器,创建的迭代器以n元组的形式返回,n的默认值为2,此函数适用于任何可迭代的对象,但是,为了克隆原始迭代器,生成的项会被缓存,并在所有新创建的迭代器中使用,一定要注意,不要在调用tee()之后使用原始迭代器iterable,否则缓存机制可能无法正确工作。
把一个迭代器分为n个迭代器, 返回一个元组.默认是两个
- def tee(iterable, n=2):
- it = iter(iterable)
- deques = [collections.deque() for i in range(n)]
- def gen(mydeque):
- while True:
- if not mydeque: # when the local deque is empty
- newval = next(it) # fetch a new value and
- for d in deques: # load it to all the deques
- d.append(newval)
- yield mydeque.popleft()
- return tuple(gen(d) for d in deques)
使用
- from itertools import *
- r = islice(count(), 5)
- i1, i2 = tee(r)
- for i in i1:
- print 'i1:', i
- for i in i2:
- print 'i2:', i
- i1: 0
- i1: 1
- i1: 2
- i1: 3
- i1: 4
- i2: 0
- i2: 1
- i2: 2
- i2: 3
- i2: 4
itertools.takewhile(predicate, iterable)
和dropwhile相反
创建一个迭代器,生成iterable中predicate(item)为True的项,只要predicate计算为False,迭代就会立即停止。
即:从序列的头开始, 直到执行函数func失败.
- def takewhile(predicate, iterable):
- # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
- for x in iterable:
- if predicate(x):
- yield x
- else:
- break
使用
- from itertools import *
- def should_take(x):
- print 'Testing:', x
- return (x<2)
- for i in takewhile(should_take, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
- print 'Yielding:', i
- Testing: -1
- Yielding: -1
- Testing: 0
- Yielding: 0
- Testing: 1
- Yielding: 1
- Testing: 2
itertools.izip(*iterables)
返回一个合并了多个迭代器为一个元组的迭代器. 它类似于内置函数zip(), 只是它返回的是一个迭代器而不是一个列表
创建一个迭代器,生成元组(i1, i2, ... iN),其中i1,i2 ... iN 分别来自迭代器iter1,iter2 ... iterN,只要提供的某个迭代器不再生成值,迭代就会停止,此函数生成的值与内置的zip()函数相同。
- izip(iter1, iter2, ... iterN):
- 返回:(it1[0],it2 [0], it3[0], ..), (it1[1], it2[1], it3[1], ..)...
- def izip(*iterables):
- # izip('ABCD', 'xy') --> Ax By
- iterators = map(iter, iterables)
- while iterators:
- yield tuple(map(next, iterators))
使用
- from itertools import *
- for i in izip([1, 2, 3], ['a', 'b', 'c']):
- print i
- (1, 'a')
- (2, 'b')
- (3, 'c')
itertools.izip_longest(*iterables[, fillvalue])
与izip()相同,但是迭代过程会持续到所有输入迭代变量iter1,iter2等都耗尽为止,如果没有使用fillvalue关键字参数指定不同的值,则使用None来填充已经使用的迭代变量的值。
- class ZipExhausted(Exception):
- pass
- def izip_longest(*args, **kwds):
- # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
- fillvalue = kwds.get('fillvalue')
- counter = [len(args) - 1]
- def sentinel():
- if not counter[0]:
- raise ZipExhausted
- counter[0] -= 1
- yield fillvalue
- fillers = repeat(fillvalue)
- iterators = [chain(it, sentinel(), fillers) for it in args]
- try:
- while iterators:
- yield tuple(map(next, iterators))
- except ZipExhausted:
- pass
第三部分
itertools.product(*iterables[, repeat])
笛卡尔积
创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔积的元组,repeat是一个关键字参数,指定重复生成序列的次数。
- def product(*args, **kwds):
- # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
- # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
- pools = map(tuple, args) * kwds.get('repeat', 1)
- result = [[]]
- for pool in pools:
- result = [x+[y] for x in result for y in pool]
- for prod in result:
- yield tuple(prod)
例子
- import itertools
- a = (1, 2, 3)
- b = ('A', 'B', 'C')
- c = itertools.product(a,b)
- for elem in c:
- print elem
- (1, 'A')
- (1, 'B')
- (1, 'C')
- (2, 'A')
- (2, 'B')
- (2, 'C')
- (3, 'A')
- (3, 'B')
- (3, 'C')
itertools.permutations(iterable[, r])
排列
创建一个迭代器,返回iterable中所有长度为r的项目序列,如果省略了r,那么序列的长度与iterable中的项目数量相同: 返回p中任意取r个元素做排列的元组的迭代器
- def permutations(iterable, r=None):
- # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
- # permutations(range(3)) --> 012 021 102 120 201 210
- pool = tuple(iterable)
- n = len(pool)
- r = n if r is None else r
- if r > n:
- return
- indices = range(n)
- cycles = range(n, n-r, -1)
- yield tuple(pool[i] for i in indices[:r])
- while n:
- for i in reversed(range(r)):
- cycles[i] -= 1
- if cycles[i] == 0:
- indices[i:] = indices[i+1:] + indices[i:i+1]
- cycles[i] = n - i
- else:
- j = cycles[i]
- indices[i], indices[-j] = indices[-j], indices[i]
- yield tuple(pool[i] for i in indices[:r])
- break
- else:
- return
- 也可以用product实现
- def permutations(iterable, r=None):
- pool = tuple(iterable)
- n = len(pool)
- r = n if r is None else r
- for indices in product(range(n), repeat=r):
- if len(set(indices)) == r:
- yield tuple(pool[i] for i in indices)
itertools.combinations(iterable, r)
创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序 (不带重复)
- def combinations(iterable, r):
- # combinations('ABCD', 2) --> AB AC AD BC BD CD
- # combinations(range(4), 3) --> 012 013 023 123
- pool = tuple(iterable)
- n = len(pool)
- if r > n:
- return
- indices = range(r)
- yield tuple(pool[i] for i in indices)
- while True:
- for i in reversed(range(r)):
- if indices[i] != i + n - r:
- break
- else:
- return
- indices[i] += 1
- for j in range(i+1, r):
- indices[j] = indices[j-1] + 1
- yield tuple(pool[i] for i in indices)
#或者
- def combinations(iterable, r):
- pool = tuple(iterable)
- n = len(pool)
- for indices in permutations(range(n), r):
- if sorted(indices) == list(indices):
- yield tuple(pool[i] for i in indices)
itertools.combinations_with_replacement(iterable, r)
创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序 (带重复)
- def combinations_with_replacement(iterable, r):
- # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
- pool = tuple(iterable)
- n = len(pool)
- if not n and r:
- return
- indices = [0] * r
- yield tuple(pool[i] for i in indices)
- while True:
- for i in reversed(range(r)):
- if indices[i] != n - 1:
- break
- else:
- return
- indices[i:] = [indices[i] + 1] * (r - i)
- yield tuple(pool[i] for i in indices)
或者
- def combinations_with_replacement(iterable, r):
- pool = tuple(iterable)
- n = len(pool)
- for indices in product(range(n), repeat=r):
- if sorted(indices) == list(indices):
- yield tuple(pool[i] for i in indices)
第四部分
扩展
使用现有扩展功能
- def take(n, iterable):
- "Return first n items of the iterable as a list"
- return list(islice(iterable, n))
- def tabulate(function, start=0):
- "Return function(0), function(1), ..."
- return imap(function, count(start))
- def consume(iterator, n):
- "Advance the iterator n-steps ahead. If n is none, consume entirely."
- # Use functions that consume iterators at C speed.
- if n is None:
- # feed the entire iterator into a zero-length deque
- collections.deque(iterator, maxlen=0)
- else:
- # advance to the empty slice starting at position n
- next(islice(iterator, n, n), None)
- def nth(iterable, n, default=None):
- "Returns the nth item or a default value"
- return next(islice(iterable, n, None), default)
- def quantify(iterable, pred=bool):
- "Count how many times the predicate is true"
- return sum(imap(pred, iterable))
- def padnone(iterable):
- """Returns the sequence elements and then returns None indefinitely.
- Useful for emulating the behavior of the built-in map() function.
- """
- return chain(iterable, repeat(None))
- def ncycles(iterable, n):
- "Returns the sequence elements n times"
- return chain.from_iterable(repeat(tuple(iterable), n))
- def dotproduct(vec1, vec2):
- return sum(imap(operator.mul, vec1, vec2))
- def flatten(listOfLists):
- "Flatten one level of nesting"
- return chain.from_iterable(listOfLists)
- def repeatfunc(func, times=None, *args):
- """Repeat calls to func with specified arguments.
- Example: repeatfunc(random.random)
- """
- if times is None:
- return starmap(func, repeat(args))
- return starmap(func, repeat(args, times))
- def pairwise(iterable):
- "s -> (s0,s1), (s1,s2), (s2, s3), ..."
- a, b = tee(iterable)
- next(b, None)
- return izip(a, b)
- def grouper(iterable, n, fillvalue=None):
- "Collect data into fixed-length chunks or blocks"
- # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
- args = [iter(iterable)] * n
- return izip_longest(fillvalue=fillvalue, *args)
- def roundrobin(*iterables):
- "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
- # Recipe credited to George Sakkis
- pending = len(iterables)
- nexts = cycle(iter(it).next for it in iterables)
- while pending:
- try:
- for next in nexts:
- yield next()
- except StopIteration:
- pending -= 1
- nexts = cycle(islice(nexts, pending))
- def powerset(iterable):
- "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
- s = list(iterable)
- return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
- def unique_everseen(iterable, key=None):
- "List unique elements, preserving order. Remember all elements ever seen."
- # unique_everseen('AAAABBBCCDAABBB') --> A B C D
- # unique_everseen('ABBCcAD', str.lower) --> A B C D
- seen = set()
- seen_add = seen.add
- if key is None:
- for element in ifilterfalse(seen.__contains__, iterable):
- seen_add(element)
- yield element
- else:
- for element in iterable:
- k = key(element)
- if k not in seen:
- seen_add(k)
- yield element
- def unique_justseen(iterable, key=None):
- "List unique elements, preserving order. Remember only the element just seen."
- # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
- # unique_justseen('ABBCcAD', str.lower) --> A B C A D
- return imap(next, imap(itemgetter(1), groupby(iterable, key)))
- def iter_except(func, exception, first=None):
- """ Call a function repeatedly until an exception is raised.
- Converts a call-until-exception interface to an iterator interface.
- Like __builtin__.iter(func, sentinel) but uses an exception instead
- of a sentinel to end the loop.
- Examples:
- bsddbiter = iter_except(db.next, bsddb.error, db.first)
- heapiter = iter_except(functools.partial(heappop, h), IndexError)
- dictiter = iter_except(d.popitem, KeyError)
- dequeiter = iter_except(d.popleft, IndexError)
- queueiter = iter_except(q.get_nowait, Queue.Empty)
- setiter = iter_except(s.pop, KeyError)
- """
- try:
- if first is not None:
- yield first()
- while 1:
- yield func()
- except exception:
- pass
- def random_product(*args, **kwds):
- "Random selection from itertools.product(*args, **kwds)"
- pools = map(tuple, args) * kwds.get('repeat', 1)
- return tuple(random.choice(pool) for pool in pools)
- def random_permutation(iterable, r=None):
- "Random selection from itertools.permutations(iterable, r)"
- pool = tuple(iterable)
- r = len(pool) if r is None else r
- return tuple(random.sample(pool, r))
- def random_combination(iterable, r):
- "Random selection from itertools.combinations(iterable, r)"
- pool = tuple(iterable)
- n = len(pool)
- indices = sorted(random.sample(xrange(n), r))
- return tuple(pool[i] for i in indices)
- def random_combination_with_replacement(iterable, r):
- "Random selection from itertools.combinations_with_replacement(iterable, r)"
- pool = tuple(iterable)
- n = len(pool)
- indices = sorted(random.randrange(n) for i in xrange(r))
- return tuple(pool[i] for i in indices)
- def tee_lookahead(t, i):
- """Inspect the i-th upcomping value from a tee object
- while leaving the tee object at its current position.
- Raise an IndexError if the underlying iterator doesn't
- have enough values.
- """
- for value in islice(t.__copy__(), i, None):
- return value
- raise IndexError(i)
自定义扩展
将序列按大小切分,更好的性能
- from itertools import chain, islice
- def chunks(iterable, size, format=iter):
- it = iter(iterable)
- while True:
- yield format(chain((it.next(),), islice(it, size - 1)))
- >>> l = ["a", "b", "c", "d", "e", "f", "g"]
- >>> for chunk in chunks(l, 3, tuple):...
- print chunk...
- ("a", "b", "c")
- ("d", "e", "f")
- ("g",)
补充
迭代工具,你最好的朋友
迭代工具模块包含了操做指定的函数用于操作迭代器。想复制一个迭代器出来?链接两个迭代器?以one liner(这里的one-liner只需一行代码能搞定的任务)用内嵌的列表组合一组值?不使用list创建Map/Zip?···,你要做的就是 import itertools,举个例子吧:
四匹马赛跑到达终点排名的所有可能性:
- >>> horses = [1, 2, 3, 4]
- >>> races = itertools.permutations(horses)
- >>> print(races)
- <itertools.permutations object at 0xb754f1dc]]>
- >>> print(list(itertools.permutations(horses)))
- [(1, 2, 3, 4),
- (1, 2, 4, 3),
- (1, 3, 2, 4),
- (1, 3, 4, 2),
- (1, 4, 2, 3),
- (1, 4, 3, 2),
- (2, 1, 3, 4),
- (2, 1, 4, 3),
- (2, 3, 1, 4),
- (2, 3, 4, 1),
- (2, 4, 1, 3),
- (2, 4, 3, 1),
- (3, 1, 2, 4),
- (3, 1, 4, 2),
- (3, 2, 1, 4),
- (3, 2, 4, 1),
- (3, 4, 1, 2),
- (3, 4, 2, 1),
- (4, 1, 2, 3),
- (4, 1, 3, 2),
- (4, 2, 1, 3),
- (4, 2, 3, 1),
- (4, 3, 1, 2),
- (4, 3, 2, 1)]
理解迭代的内部机制: 迭代(iteration)就是对可迭代对象(iterables,实现了__iter__()方法)和迭代器(iterators,实现了__next__()方法)的一个操作过程。可迭代对象是任何可返回一个迭代器的对象,迭代器是应用在迭代对象中迭代的对象,换一种方式说的话就是:iterable对象的__iter__()方法可以返回iterator对象,iterator通过调用next()方法获取其中的每一个值(译者注),读者可以结合Java API中的 Iterable接口和Iterator接口进行类比。
Python itertools模块详解的更多相关文章
- [转载] Python itertools模块详解
原文在这里,写的很详细,感谢原作者,以下摘录要点. itertools用于高效循环的迭代函数集合. 无限迭代器 迭代器 参数 结果 例子 count() start, [step] start, st ...
- (转)python collections模块详解
python collections模块详解 原文:http://www.cnblogs.com/dahu-daqing/p/7040490.html 1.模块简介 collections包含了一些特 ...
- python time模块详解
python time模块详解 转自:http://blog.csdn.net/kiki113/article/details/4033017 python 的内嵌time模板翻译及说明 一.简介 ...
- python docopt模块详解
python docopt模块详解 docopt 本质上是在 Python 中引入了一种针对命令行参数的形式语言,在代码的最开头使用 """ ""&q ...
- python pathlib模块详解
python pathlib模块详解
- Python Fabric模块详解
Python Fabric模块详解 什么是Fabric? 简单介绍一下: Fabric是一个Python的库和命令行工具,用来提高基于SSH的应用部署和系统管理效率. 再具体点介绍一下,Fabri ...
- python time 模块详解
Python中time模块详解 发表于2011年5月5日 12:58 a.m. 位于分类我爱Python 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括: ...
- python常用模块详解
python常用模块详解 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用p ...
- python os模块详解
一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...
随机推荐
- 【mysql】datetime时间比较
如下,比较的日期用指定格式写出就可以了.不需要日期函数. SELECT * FROM table_a WHERE write_date > "2017-07-17 00:00:00&q ...
- Linux基础一:Linux的安装及相关配置
1. 计算机操作系统简介 1) 操作系统的定义:操作系统是一个用来协调.管理和控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间. 2) 操作系统的内核的定义:操作系统的内核是一 ...
- spring cloud 声明式rest客户端feign调用远程http服务
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...
- Html页面添加百度地图
1.进入百度地图开放平台 http://lbsyun.baidu.com/ 2.进入右上角的 “API控制台” 在这里创建应用 并 获取密钥 3.进入 如下地址 创建地图 http://api.m ...
- Python os.walk() 方法遍历文件目录
概述 os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下. os.walk() 方法是一个简单易用的文件.目录遍历器,可以帮助我们高效的处理文件.目录方面的事情. 在Un ...
- Caused by: java.lang.NumberFormatException: For input string: "18446744073709551615"
问题:Caused by: java.lang.NumberFormatException: For input string: "18446744073709551615" 原因 ...
- JavaScript中this 详解
涵义 this 关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先, this 总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. this.p ...
- mysql恢复ibd文件
1.将原表删除,包括ibd和frm文件 2.重新创建表结构. 3.丢弃表空间 alter table tableName discard tablespace; 4.将要恢复的ibd文件拷贝到数据库目 ...
- js 2017
JS面向对象 <script> function num(val) { return val * 8 } function Index(name, age) { this.name = n ...
- springboot学习(一):创建项目
package com.glory.demo.Controller; import org.springframework.stereotype.Controller; import org.spri ...