遍历两个列表的列表理解没有按预期工作[重复]
Posted
技术标签:
【中文标题】遍历两个列表的列表理解没有按预期工作[重复]【英文标题】:List comprehension iterating over two lists is not working as expected [duplicate] 【发布时间】:2019-06-22 13:59:06 【问题描述】:我想遍历两个列表。第一个列表包含一些浏览器用户代理,第二个列表包含这些浏览器的版本。我只想过滤掉那些版本大于 60 的用户代理。
这是我的列表理解的样子:
[link for ver in version for link in useragents if ver > 60]
这个列表的问题是它多次打印同一个用户代理。我使用zip
函数编写了以下内容,效果很好:
for link, ver in zip(useragents, version):
if ver > 60:
# append to list
print(link)
为什么我的列表理解返回了意外的结果?
【问题讨论】:
【参考方案1】:[link for (link, ver) in zip(useragents, version) if ver > 60]
您仍然需要将两个列表压缩在一起。
【讨论】:
【参考方案2】:您的第一个列表理解相当于:
res = []
for ver in version:
for link in useragents:
if ver > 60:
res.append(link)
请注意,您有时间复杂度为 O(n2) 的嵌套循环,即您正在迭代 version
的每个组合 和useragents
。这不是您想要的,假设您的 version
和 useragents
列表是对齐的。
您的for
循环等效于以下列表理解:
res = [link for link, ver in zip(useragents, version) if ver > 60]
【讨论】:
【参考方案3】:如果没有您的数据,无法确定发生了什么,但总的来说,“双重”列表理解与 zip
不同,而是一个双重循环,即
[a for b in bs for a in as]
等价于
for b in bs:
for a in as:
lst.append(a)
【讨论】:
【参考方案4】:这个
[link for ver in version for link in useragents if ver > 60]
与 zip 不同。它不是并行遍历两个序列。它正在遍历这两个序列的所有组合。
好像你写的:
for ver in version:
for link in useragents:
if ver > 60:
# append(link)
因此,如果两个序列的长度均为 5,则将有 25 种组合(其中一些被条件 ver > 60
过滤掉)。
当您想并行处理序列时,zip
是实现它的方法,即使在理解中也是如此。
[link for (link, ver) in zip(useragents, version) if ver > 60]
【讨论】:
【参考方案5】:或者,您可以将函数compress()
与map()
结合使用,在其中检查一些条件:
from itertools import compress
filter_ = map(lambda x: x > 60, version)
list(compress(useragents, filter_))
示例:
s = 'ABCDEFG'
nums = range(len(s))
filter_ = map(lambda x: x > 3, nums)
print(list(compress(s, filter_)))
# ['E', 'F', 'G']
【讨论】:
以上是关于遍历两个列表的列表理解没有按预期工作[重复]的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:当“navigationBarItems”修改列表时,“listRowInsets”无法按预期工作[重复]