为什么zip(*)无法恢复我的原始列表

时间:2018-08-16 09:17:30

标签: python list

我正试图了解正在发生的事情:

a = list('hello world')
b = [a[i::l]for i in range(8)]

然后我会期望:

zip(*b) == a

但是我得到的是以下内容:

 [('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o')]

也许我无法理解zip(*)的作用,但是我认为它解压缩了一个列表列表,并从中列出了一个列表。我要去哪里错了?

2 个答案:

答案 0 :(得分:2)

您错过了zip()的详细信息,如outlined in the documentation

  

最短的可迭代输入耗尽时,迭代器停止

hello world中有11个字符,一个质数,因此,除了11个单独序列的列表(每个序列都有一个字符)之外,如果没有至少一个较短的列表,则无法生成列表列表

例如,如果我们假设l = 8(大于等于5的任何值都会产生您显示的输出),那么a设置为:

[['h', 'r'], ['e', 'l'], ['l', 'd'], ['l'], ['o'], [' '], ['w'], ['o']]

共有8个列表,其中第一个包含2个元素,其余的只有一个。因此,只有这些元素的 first元素用于生成组合:

>>> [l[0] for l in b]
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o']

您只循环了8次,因此b中只有8个顶级列表可以接收信件。对于l的5或更高的不同值,您将得到剩余字母的不同分布,但是仅剩余3个字符,就没有很多方法可以将剩余的字母分布在整个列表中,而{{ 1}}在l下方,您只需添加重复的字母(因为8[0::l]对于等于或小于7的任何[7::l]都可以重叠)。

您必须最多循环11次,并每11个字符使用一次,即可获得将压缩到相同序列的内容:

l

这仍然与>>> b = [a[i::11]for i in range(11)] >>> b [['h'], ['e'], ['l'], ['l'], ['o'], [' '], ['w'], ['o'], ['r'], ['l'], ['d']] >>> list(zip(*b)) [('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd')] 不同,因为a产生序列序列(这里只是一个序列,因为每个嵌套列表中只有一个值)。您可以使用zip()获取第一个(也是唯一一个)元素:

next()

您可以改为使用itertools.zip_longest()来继续迭代,直到用完最长可输入的 为止,并添加默认的填充值以增加较短的序列。如果您想再次将序列重新连接回整个字符串,则可以使用空字符串:

>>> a == list(next(zip(*b)))
True

这会生成两个元组;毕竟输入中有两列:

try:
    # Python 3
    from itertools import zip_longest
except ImportError:
    # Python 2 has the same object, but with i prefixed
    from itertools import izip_longest as zip_longest

result = list(zip_longest(*b, fillvalue=''))

您必须将它们链接起来以重新组合它们; itertools.chain.from_iterable()可以做到:

>>> from itertools import zip_longest
>>> b = [a[i::8]for i in range(8)]
>>> list(zip_longest(*b, fillvalue=''))
[('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o'), ('r', 'l', 'd', '', '', '', '', '')]

这再次仅适用于>>> from itertools import chain >>> ''.join(chain.from_iterable(zip_longest(*b, fillvalue=''))) 'hello world' ,这是因为l = 8的较低值的切片重叠,对于l,您从头开始缺少了8个{ {1}}个切片包括这些字符

l > 8

答案 1 :(得分:0)

您的代码不清楚,我们也不知道l到底是什么!如果您按原样运行它,您肯定会收到一条错误消息,说明未定义l。

但是,对于zip函数,它在最短的迭代器处停止,要使其继续运行,您应该使用zip_longest

有关zip功能如何工作的更多详细信息,请检查以下内容:Python zip