带有if语句的列表推导式

143

我想比较两个可迭代对象,并打印出在两个可迭代对象中都出现的项目。

>>> a = ('q', 'r')
>>> b = ('q')


# Iterate over a. If y not in b, print y.
# I want to see ['r'] printed.
>>> print([ y if y not in b for y in a])
                              ^

但是它给了我一个无效的语法错误,其中^被放置。

这个lambda函数有什么问题?


5
下面的所有答案都是正确的,但是b = ('q')并不创建一个元组。只有显式加上逗号的单元素元组才能被创建,即b = ('q',) - dmg
我已经将“元组”更改为“可迭代对象”。 - OrangeTux
这个 lambda 函数有什么问题吗?...这里没有 lambda 函数。 - Anentropic
5个回答

256

您的顺序错了,if 应该在 for 之后(除非它在一个 if-else 三目运算符中)

[y for y in a if y not in b]

这个可以工作,然而:

[y if y not in b else other_value for y in a]

谢谢。我看到了这篇文章https://dev59.com/lG855IYBdhLWcg3wViot,关于在lambda函数中使用if else语句。我认为只使用if语句(不带else)会按照相同的顺序工作。 - OrangeTux

52

你把if放在最后:

[y for y in a if y not in b]

列表推导式的书写顺序与它们嵌套的完整指定版本相同,本质上,上述语句的翻译如下:

outputlist = []
for y in a:
    if y not in b:
        outputlist.append(y)

你的版本试图做相反的事情:

outputlist = []
if y not in b:
    for y in a:
        outputlist.append(y)

但列表推导式必须以至少一个外部循环开始。


9

列表推导式公式:

[<value_when_condition_true> if <condition> else <value_when_condition_false> for value in list_name]

因此,您可以这样做:
[y for y in a if y not in b]

仅用于演示目的: [y if y不在b中 else False for y in a]


2
你不能在列表推导式中放置一个 else,至少不是在你放置的位置。不要将列表推导式(过滤)与条件表达式混淆(必须具有值,因此需要 else 表达式)。 - Martijn Pieters
1
同意。在列表推导式中可以使用 else,就像代码中所示。 - Vishvajit Pathak
2
这是一个条件表达式。它可以在任何有效表达式适用的地方使用。它与列表推导无关。 - Martijn Pieters

5

这不是一个lambda函数,而是一个列表推导式。

只需要改变顺序即可:

[ y for y in a if y not in b]

1
如果您使用足够大的列表,not in b子句将对a中的每个项目进行线性搜索。为什么不使用集合?集合以可迭代对象作为参数创建新的集合对象。
>>> a = ["a", "b", "c", "d", "e"]
>>> b = ["c", "d", "f", "g"]
>>> set(a).intersection(set(b))
{'c', 'd'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接