文章来自《Python cookbook》.

翻译仅仅是为了个人学习,其它商业版权纠纷与此无关!

-- Zoom.Quiet [2004-08-11 01:08:20]

1. 解包简单的类list对象

1.12 Unzipping Simple List-Like Objects

Credit: gyro funch

1.1. 问题 Problem

You have a sequence and need to pull it apart into a number of pieces.

你有一个序列并且需要把它分别放到一些片断中.

1.2. 解决 Solution

There's no built-in unzip counterpart to zip, but it's not hard to code our own:

没有内建的zip的配对unzip.但是编写一个我们自己的也不是很困难:

   1 def unzip(p, n):
   2     """ Split a sequence p into a list of n tuples, repeatedly taking the
   3     next unused element of p and adding it to the next tuple.  Each of the
   4     resulting tuples is of the same length; if p%n != 0, the shorter tuples
   5     are padded with None (closer to the behavior of map than to that of zip).
   6         Example:
   7         >>> unzip(['a','b','c','d','e'], 3)
   8         [('a', 'd'), ('b', 'e'), ('c', None)]
   9     """
  10     # First, find the length for the longest sublist
  11     #首先,发现最长的子list的长度
  12      mlen, lft = divmod(len(p), n)
  13     if lft != 0: mlen += 1
  14 
  15     # Then, initialize a list of lists with suitable lengths
  16     #然后,用合适的长度的list来初始化一个list 
  17     lst = [[None]*mlen for i in range(n)]
  18 
  19     # Loop over all items of the input sequence (index-wise), and
  20     # Copy a reference to each into the appropriate place
  21     #在所有元素上的输入次序(索引方式)做循环,并且拷贝每一个的引用到合适的地方
  22     for i in range(len(p)):
  23         j, k = divmod(i, n)    # Find sublist-index and index-within-sublist
  24         lst[k][j] = p[i]       # Copy a reference appropriately
  25 
  26     # Finally, turn each sublist into a tuple, since the unzip function
  27     # is specified to return a list of tuples, not a list of lists
  28     #最后,把每个子list转换称tuple.因为unzip函数被指定要返回一个tuple的列表.而不是一个list的列表的
  29     return map(tuple, lst)

1.3. 讨论 Discussion

The function in this recipe takes a list and pulls it apart into a user-defined number of pieces. It acts like a sort of reverse zip function (although it deals with only the very simplest cases). This recipe was useful to me recently when I had to take a Python list and break it down into a number of different pieces, putting each consecutive item of the list into a separate sublist.

在这个配方里的函数带一个list,并且把它部分地放到用户定义的片断中.它的活动象一个zip函数反作用(尽管它处理非常简单的情况).最近当我不得不带着一个python list并且把它分成几个不同的片断,把list的每个连续元素放到一个分隔的子list的时候,这个配方对我特别有用.

Preallocating the result as a list of lists of None is generally more efficient than building up each sublist by repeated calls to append. Also, in this case, it already ensures the padding with None that we would need anyway (unless length(p) just happens to be a multiple of n).

预先分配一系列为None的list一般比通过重复调用append来建造每个子list更有效率.同样,既然这样,无论如何它也确保用我们需要的None来填充(除非length(p)碰巧是n的倍数)

The algorithm that unzip uses is quite simple: a reference to each item of the input sequence is placed into the appropriate item of the appropriate sublist. The built-in function divmod computes the quotient and remainder of a division, which just happen to be the indexes we need for the appropriate sublist and item in it.

Unzip使用的算法相当简单:输入序列每个元素的引用被放置到合适的子序列的合适的条目上.内建的函数divmod计算商和余数,他们刚好是我们所需要的子list和它的元素的索引

Although we specified that unzip must return a list of tuples, we actually build a list of sublists, and we turn each sublist into a tuple as late in the process as possible by applying the built-in function tuple over each sublist with a single call to map. It is much simpler to build sublists first. Lists are mutable, so we can bind specific items separately; tuples are immutable, so we would have a harder time working with them in our unzip function's main loop.

尽管我们 指定unzip必须返回tuple的list,我们实际上建立了一系列的子list.并且我们转化每个子list到一个tuple.尽可能在这个过程中通过在每个单独调用map的子list使用内建函数tuple.

1.4. 参考 See Also

Documentation for the zip and divmod built-ins in the Library Reference.