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

# 解包简单的类list对象

1.12 Unzipping Simple List-Like Objects

Credit: gyro funch

## 问题 Problem

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

## 解决 Solution

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

```   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)
```

## 讨论 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.

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).

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.

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

PyCkBk-1-12 (last edited 2009-12-25 07:18:03 by localhost)

• Page.execute = 1.164s
• getACL = 0.260s
• init = 0.004s