程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> Python itertools模塊詳解

Python itertools模塊詳解

編輯:更多關於編程

       篇文章主要介紹了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)

      

      >>> 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接口進行類比。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved