python列表理解 - 使用任何

Posted

技术标签:

【中文标题】python列表理解 - 使用任何【英文标题】:python list comprehension - use of any 【发布时间】:2021-01-17 01:30:59 【问题描述】:
test_list = [(1, 4, 6), (5, 8), (2, 9), (1, 10)] 
 
tar_list = [6, 10] 

从测试列表中保留包含任何目标列表元素的元组:

Filtered tuple from list are : [(1, 4, 6), (1, 10)]

我完成上述简单任务的代码:

lst =[]
for tup in test_list:
    for i in tar_list:
        if i in tup:
            lst.append(tup)

列表理解解决方案:

res = [tup for tup in test_list if any(i in tup for i in tar_list)]

谁能解释一下“any”在这里的作用是什么? 第一轮 - tup -> 1,4,6 如果 cond 为 tar_list[0] 返回 true,即 6,然后在 tar_list[1] 检查值 10,它返回 false。如果我不使用 ANY,则考虑 false 并且 tup 不应出现在最终列表 res 中。那是对的吗?我有点理解这里的任何用法,但想了解为什么在这种情况下第一个元组会在 res 列表中。

【问题讨论】:

“想了解为什么在这种情况下第一个元组会出现在 res 列表中” - 请与您所做的更改共享代码,这会给您带来您难以理解的结果。 我认为你没有做对。 any() 将遍历一系列元素,如果至少一个元素具有真值,则返回 true,否则返回 false。如果你不在那里使用any(),你会留下if (i in tup for i in tar_list),它总是返回true,因为生成器不是“假的”。 如果 for 循环正确输出是:[(1, 4, 6), (1, 10)] 并且对于没有“任何”子句的列表理解返回 [(1, 4, 6 ), (5, 8), (2, 9), (1, 10)]。但是当我们使用“any”子句时,它会像 for 循环一样返回正确的输出。我已经为“for循环”以及列表理解共享了上面的代码。我希望这次我清楚了。谢谢。 @Reti43 不真/假取决于“我是否在 tup”?。 你一直说“没有any”,但如果你删除any,剩下的表达式就是一个生成器,它的计算结果总是True 【参考方案1】:

如果您考虑嵌套 for 循环:

for i in tar_list:
    if i in tup:
        lst.append(tup)

这将遍历tar_list 中的值,如果其中任何在当前tup 值中,则tup 值将添加到lst

作为一个列表推导式,你把这个条件写成

if any(i in tup for i in tar_list)

现在,如果每个 tup 值仅包含来自 tar_list 的一个值,则这些结果相同。考虑这种情况:

test_list = [(1, 4, 6), (5, 8), (2, 9), (1, 10)] 
tar_list = [4, 6]

在这种情况下,您的原始循环会将第一个元组附加到输出两次,而列表推导只会附加一次。

lst =[]
for tup in test_list:
    for i in tar_list:
        if i in tup:
            lst.append(tup)
print(lst)

lst = [tup for tup in test_list if any(i in tup for i in tar_list)]
print(lst)

输出

[(1, 4, 6), (1, 4, 6)]
[(1, 4, 6)]

您可以通过在附加到lst 之后添加break 来防止原始循环重复:

lst =[]
for tup in test_list:
    for i in tar_list:
        if i in tup:
            lst.append(tup)
            break

如果您确实想将元组附加到输出列表两次,则需要将您的理解修改为与原始循环完全相同

lst = [tup for tup in test_list for i in tar_list if i in tup]

输出(针对上述数据):

[(1, 4, 6), (1, 4, 6)]

【讨论】:

【参考方案2】:

any 只检查列表中的任何值是否为真。如果您只想过滤到单个 tar_value,这很简单:只需使用列表推导过滤 [tup for tup in test_list if tar_value in tup]

但是,您想检查tar_list 中的任何 值是否存在于test_list 中。所以i in tup for i in tar_list 部分只是对tar_list 中的每个元素运行上述测试。由于您想保留其中包含 6 个 10 个的元素,因此您可以使用 any 来检查是否有任何元素返回 true。如果你想检查 6 and 10 在元素中的位置,你可以使用 all

【讨论】:

【参考方案3】:

any() 将通过一个布尔迭代器并在元素之间执行or 操作(不完全是,但足够接近)。因此,如果它找到 1 个或多个 True 值,则返回 True,否则将返回 False

tup = (1, 10)
tar_list = [6, 10] 

print([i in tup for i in tar_list])
# Output: [False, True]
print(any([i in tup for i in tar_list]))
# Output: True

所以any() 返回一个布尔值。现在看看你的代码

res = [tup for tup in test_list if any(i in tup for i in tar_list)]

您正在执行列表推导,并使用if 条件。对于您通过test_list 的每个元组,您检查tar_list 中的任何元素是否存在于元组中。如果是这样,你会得到一个 True 并添加它,否则你会得到一个 False 并且你不添加它。

【讨论】:

以上是关于python列表理解 - 使用任何的主要内容,如果未能解决你的问题,请参考以下文章

Python 基础2 - 列表

深入理解python中的排序sort

python 使用列表理解从两个列表中的字典

使用 if 和 break 创建 Python 列表推导式

Python IZIP 列表理解返回空列表

深入理解python列表和元组