python - 为什么 zip(*) 没有恢复我的原始列表
问题描述
我试图了解正在发生的事情:
a = list('hello world')
b = [a[i::l]for i in range(8)]
然后我会期望:
zip(*b) == a
但是我得到的是以下内容:
[('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o')]
也许我无法理解 zip(*) 的作用,但我认为它会解压缩列表列表并从中生成一个列表。我哪里错了?
解决方案
zip()
如文档中所述,您错过了特定于 的详细信息:
当最短的输入迭代用尽时,迭代器停止
hello world
其中有 11 个字符,一个素数,因此除了每个字符的 11 个单独序列的列表之外,如果没有至少一个更短的列表,就无法生成列表列表。
例如,如果我们假设l = 8
(5 岁及以上的任何东西都会产生您显示的输出),则a
设置为:
[['h', 'r'], ['e', 'l'], ['l', 'd'], ['l'], ['o'], [' '], ['w'], ['o']]
那是 8 个列表,第一个包含 2 个元素,其余的只有一个。因此,只有其中的第一个元素用于生成组合:
>>> [l[0] for l in b]
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o']
您只循环了 8 次,因此只有 8 个顶级列表b
可以从中获取字母。对于l
5 或以上的不同值,您将获得剩余字母的不同分布,但只剩下 3 个字符,没有太多方法可以在列表中分配这些剩余字母,并且在l
下面8
,您只需添加重复的字母(因为[0::l]
并且[7::l]
保证在l
等于或小于 7 时重叠)。
您必须循环最多 11 次并获取每 11 个字符才能获得将压缩到相同序列的内容:
>>> 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()
用来获取第一个(也是唯一一个)元素:
>>> a == list(next(zip(*b)))
True
您可以改为使用itertools.zip_longest()
继续迭代,直到用尽最长的输入迭代,并添加默认填充值以增加较短的序列。如果您想再次将序列连接回整个字符串,则可以使用空字符串:
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=''))
然而,这会产生两个元组;毕竟,输入中有两列:
>>> 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', '', '', '', '', '')]
您必须将它们链接起来才能重新组合它们;itertools.chain.from_iterable()
可以这样做:
>>> from itertools import chain
>>> ''.join(chain.from_iterable(zip_longest(*b, fillvalue='')))
'hello world'
这仅适用于, 再次,因为, Forl = 8
的较低值的重叠切片,您从末尾开始缺少字符,因为 8 个切片中没有一个包含这些字符l
l > 8
a[i::l]
>>> for l in range(2, 12):
... print(f'{l:>2d}:', ''.join(chain.from_iterable(zip_longest(*[a[i::l] for i in range(8)], fillvalue=''))))
...
2: hello wollo worlo worldworldrldd
3: hello wolo worldworldld
4: hello woo worldrld
5: hello wo worldd
6: hello woworld
7: hello woorld
8: hello world
9: hello wold
10: hello wod
11: hello wo
推荐阅读
- angular - Angular App routerlinks 在开发中运行良好,但在生产中运行不正常?
- c++ - const_cast 不同的行为:原始类型与对象类型
- php - 在数据库中上传图像时文件名太长
- fiware - Fiware orion 日期格式无效
- css - 弹出不坚持保存文本
- c# - 如何在服务器端处理新的刷新令牌?
- cmake - 如何将空元素添加到 CMake 列表?
- javascript - 将 vue-gtm(谷歌标签管理器)附加到路由器实例
- csproj - 是否可以使用新的 csproj 格式为 .NET Framework Client Profile 构建?
- sql-server - 如何在连接 sql server management studio 时解决登录问题。错误是:管道的另一端没有进程(SQL Server 2014)