在Python的列表推导式中,是否有一种方法可以使用两个if条件?

39

假设我有一个列表

my_list = ['91 9925479326','18002561245','All the best','good']

现在我想忽略列表中以9118开头的字符串,如下所示:

result = []
for i in my_list:
   if not '91' in i:
      if not '18' in i:
         result.append(i) 

所以我想用列表推导式来实现这个。

在列表推导式中有没有办法写两个 if 条件?


@jamylak:我已经把那个当作一个例子了,无论如何还是谢谢你的编辑。 - Shiva Krishna Bavandla
5
请注意,你的测试只是检查字符串中是否存在 9118,无论它们在哪个位置。你应该改用 str.startswith:http://docs.python.org/library/stdtypes.html#str.startswith - Giulio Piancastelli
3个回答

54
[i for i in my_list if '91' not in i and '18' not in i]

请注意,您不应将list用作变量名,它会隐藏内置函数。


1
对于正确答案加1,并将“not '91' in i”更改为“'91' not in i”。 - mgilson
当你需要检查五个或十个值而不是两个时,这个答案就不再那么简洁和清晰了。 - Igor Chubin
我们能否使用startwith函数来实现相同的功能呢?因为有时列表中包含以91开头的字符串,有时则是以18开头的,无论如何,以91或18开头的字符串都应该从列表中忽略。实际上,这里的字符串是电话号码,例如91 9885564213和1800 3236 2365。 - Shiva Krishna Bavandla
我必须指出,这个解决方案完全不正确,你必须使用 startswith 而不是 in 来检查值。 - Igor Chubin
1
@IgorChubin - 这个答案完成了OP所要求的 - 主要是将给定的for循环转换为列表推导式。 - mgilson
@mgilson: 现在我想忽略列表中以91和18开头的字符串,如下所示 - Igor Chubin

12

如果你有超过两个值(例如91和18),或者它们是动态产生的,使用以下结构会更好:

[i for i in my_list if not i.startswith(('91', '18'))]

如果你想检查字符串中是否包含 9118(不仅在开头),请使用in而不是startswith

[i for i in my_list if all(x not in i for x in ['91', '18'])]

使用示例:

>>> my_list = ['91 9925479326','18002561245','All the best','good']
>>> [i for i in my_list if all(not i.startswith(x) for x in ['91', '18'])]
['All the best', 'good']
>>> 

1
我更喜欢:[i for i in my_list if not any(i.startswith(x) for x in ['91', '18'])] 但我想这是个人偏好。 - jamylak
1
.startswith 还可以接受一个字符串元组,因此可以缩短为 [i for i in my_list if not i.startswith(('91', '18'))] - MRAB
@MRAB:非常感谢您提供的完美提示!我已经更新了答案并加入了您的变体。非常感谢。 - Igor Chubin

3
您可以“合并”这两个条件:
if ((not '91' in i) and (not '18' in i))

6
如果不使用DeMorgan's Law,可以将其转化为:如果i中既没有包含字符串'91'也没有包含字符串'18'。使用DeMorgan's Law,可以将其简化为:如果'91''18'都不在i中。 - Blckknght

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