当您执行类似'0' or '4'
的操作时,or
运算符将验证第一个参数 ( '0'
) 是否为假,如果不是假,则返回第一个值。由于'0'
is not false (它是一个非空字符串,True
当用作布尔值时产生),它将返回第一个值,甚至不会考虑以下值:
>>> '0' or '4'
'0'
如果你重复它,你会得到相同的结果:
>>> '0' or '4' or '6' or '8'
'0'
此外,in
运算符具有更高的优先级,因此它将在 each 之前执行or
:
'0' 或 '4' 或 '6' 或 '8' 在 '88' '0'
您想要在您的条件下做的是验证结果中是否有任何值:
>>> '0' in str(i) or '4' in str(i) or '6' in str(i) or '8' in str(i)
True
>>> i = 17
>>> '0' in str(i) or '4' in str(i) or '6' in str(i) or '8' in str(i)
False
这不是最优雅的解决方案,但它是您意图的最佳翻译。
那么,什么是优雅的解决方案?正如@sven 所建议的那样,您可以创建一组(更多关于它)寻找的字符:
>>> sought = set("0468")
>>> sought
set(['0', '8', '4', '6'])
然后在您的号码中创建一组数字:
>>> i = 16
>>> set(str(i))
set(['1', '6'])
现在,看看它们是否不相交:
>>> i = 16
>>> sought.isdisjoint(set(str(i)))
False
>>> i = 17
>>> sought.isdisjoint(set(str(i)))
True
在这种情况下,如果集合不是不相交的,那么您要保留它:
>>> found = []
>>> for i in range(100):
... if sought.isdisjoint(set(str(i))):
... found.append(i)
...
>>> found
[1, 2, 3, 5, 7, 9, 11, 12, 13, 15, 17, 19, 21, 22, 23, 25, 27, 29, 31, 32, 33, 35, 37, 39, 51, 52, 53, 55, 57, 59, 71, 72, 73, 75, 77, 79, 91, 92, 93, 95, 97, 99]
大多数时候,每次你让自己创建一个for
用于过滤迭代器的循环时,你真正想要的是一个列表推导:
>>> [i for i in range(100) if sought.isdisjoint(set(str(i)))]
[1, 2, 3, 5, 7, 9, 11, 12, 13, 15, 17, 19, 21, 22, 23, 25, 27, 29, 31, 32, 33, 35, 37, 39, 51, 52, 53, 55, 57, 59, 71, 72, 73, 75, 77, 79, 91, 92, 93, 95, 97, 99]
或者,使用更笨拙但对新手更友好的构造:
>>> [i for i in range(100) if not ( '0' in str(i) or '4' in str(i) or '6' in str(i) or '8' in str(i) )]
[1, 2, 3, 5, 7, 9, 11, 12, 13, 15, 17, 19, 21, 22, 23, 25, 27, 29, 31, 32, 33, 35, 37, 39, 51, 52, 53, 55, 57, 59, 71, 72, 73, 75, 77, 79, 91, 92, 93, 95, 97, 99]