两个布尔列表上的 Python AND 运算符 - 如何?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32192163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python AND operator on two boolean lists - how?
提问by Glenn N
I have two boolean lists, e.g.,
我有两个布尔列表,例如,
x=[True,True,False,False]
y=[True,False,True,False]
I want to AND these lists together, with the expected output:
我想将这些列表与预期的输出结合在一起:
xy=[True,False,False,False]
I thought that expression x and y
would work, but came to discover that it does not: in fact, (x and y) != (y and x)
我以为这种表达x and y
会起作用,但后来发现它不起作用:事实上,(x and y) != (y and x)
Output of x and y
: [True,False,True,False]
的输出x and y
:[True,False,True,False]
Output of y and x
: [True,True,False,False]
的输出y and x
:[True,True,False,False]
Using list comprehension doeshave correct output. Whew!
使用列表理解确实有正确的输出。哇!
xy = [x[i] and y[i] for i in range(len(x)]
Mind you I could not find any reference that told me the AND operator would work as I tried with x and y. But it's easy to try things in Python.
Can someone explain to me what is happening with x and y
?
请注意,我找不到任何告诉我 AND 运算符可以像我尝试使用 x 和 y 一样工作的参考。但是在 Python 中尝试事物很容易。有人可以向我解释发生了x and y
什么吗?
And here is a simple test program:
这是一个简单的测试程序:
import random
random.seed()
n = 10
x = [random.random() > 0.5 for i in range(n)]
y = [random.random() > 0.5 for i in range(n)]
# Next two methods look sensible, but do not work
a = x and y
z = y and x
# Next: apparently only the list comprehension method is correct
xy = [x[i] and y[i] for i in range(n)]
print 'x : %s'%str(x)
print 'y : %s'%str(y)
print 'x and y : %s'%str(a)
print 'y and x : %s'%str(z)
print '[x and y]: %s'%str(xy)
采纳答案by Martijn Pieters
and
simply returns either the first or the second operand, based on their truth value. If the first operand is considered false, it is returned, otherwise the other operand is returned.
and
根据它们的真值简单地返回第一个或第二个操作数。如果认为第一个操作数为假,则返回它,否则返回另一个操作数。
Lists are considered truewhen not empty, so both lists are considered true. Their contents don't play a role here.
列表不为空时被认为是真的,所以两个列表都被认为是真的。它们的内容在这里不起作用。
Because both lists are not empty, x and y
simply returns the second list object; only if x
was empty would it be returned instead:
因为两个列表都不为空,所以x and y
只返回第二个列表对象;仅当x
为空时才会返回:
>>> [True, False] and ['foo', 'bar']
['foo', 'bar']
>>> [] and ['foo', 'bar']
[]
See the Truth value testingsectionin the Python documentation:
请参阅Python 文档中的真值测试部分:
Any object can be tested for truth value, for use in an
if
orwhile
condition or as operand of the Boolean operations below. The following values are considered false:[...]
- any empty sequence, for example,
''
,()
,[]
.[...]
All other values are considered true— so objects of many types are always true.
可以测试任何对象的真值,以用于
if
或while
条件或作为以下布尔运算的操作数。以下值被认为是错误的:[...]
- 任何空序列,例如,
''
,()
,[]
。[...]
所有其他值都被认为是真——所以许多类型的对象总是真。
(emphasis mine), and the Boolean operationssectionright below that:
(强调我的),以及正下方的布尔运算部分:
x and y
if xis false, then x, else yThis is a short-circuit operator, so it only evaluates the second argument if the first one is
True
.
x and y
如果x为假,则为x,否则为y这是一个短路运算符,因此它仅在第一个参数为 时才计算第二个参数
True
。
You indeed need to test the values containedin the lists explicitly. You can do so with a list comprehension, as you discovered. You can rewrite it with the zip()
functionto pair up the values:
您确实需要明确测试列表中包含的值。正如您发现的那样,您可以使用列表理解来做到这一点。您可以使用zip()
函数重写它以配对值:
[a and b for a, b in zip(x, y)]
回答by Cyphase
This should do what you want:
这应该做你想做的:
xy = [a and b for a, b in zip(x, y)]
The reason x and y
returns y
and y and x
returns x
is because boolean operators in python return the last value checked that determines the true-ness of the expression. Non-empty list
's evaluate to True
, and since and
requires both operands to evaluate True
, the last operand checked is the second operand. Contrast with x or y
, which would return x
because it doesn't need to check y
to determine the true-ness of the expression.
x and y
返回y
和y and x
返回的原因x
是因为 python 中的布尔运算符返回检查的最后一个值,该值确定表达式的真实性。非空list
的求值为True
,并且由于and
需要两个操作数来求值True
,因此检查的最后一个操作数是第二个操作数。与 相比x or y
,它将返回,x
因为它不需要检查y
以确定表达式的真实性。
回答by Uri Goren
You can use the zip
function
您可以使用该zip
功能
x=[True,True,False,False]
y=[True,False,True,False]
z=[a and b for a,b in zip(x,y)]
回答by chepner
and
is not necessarily a Boolean operator; it returns one of its two arguments, regardless of their type. If the first argument is false-ish (False
, numeric zero, or an empty string/container), it returns that argument. Otherwise, it returns the second argument.
and
不一定是布尔运算符;它返回它的两个参数之一,而不管它们的类型。如果第一个参数是 false-ish(False
、数字零或空字符串/容器),则返回该参数。否则,它返回第二个参数。
In your case, both x
and y
are non-empty lists, so the first argument is always true-ish, meaning x and y
returns y
and y and x
returns x
.
在您的情况下,x
和y
都是非空列表,因此第一个参数始终是 true-ish,意思是x and y
返回y
和y and x
返回x
。
回答by dawg
You could use numpy:
你可以使用 numpy:
>>> import numpy as np
>>> x=np.array([True,True,False,False])
>>> y=np.array([True,False,True,False])
>>> x & y
array([ True, False, False, False], dtype=bool)
Numpy allows numerical and logical operations on arrays such as:
Numpy 允许对数组进行数值和逻辑运算,例如:
>>> z=np.array([1,2,3,4])
>>> z+1
array([2, 3, 4, 5])
You can perform bitwise and with the &
operator.
您可以使用&
运算符执行按位和。
Instead of a list comprehension, you can use numpy to generate the boolean array directly like so:
您可以使用 numpy 直接生成布尔数组,而不是列表理解:
>>> np.random.random(10)>.5
array([ True, True, True, False, False, True, True, False, False, False], dtype=bool)
回答by Philipp
Instead of using
而不是使用
[a and b for a, b in zip(x, y)]
one could just use the possibility of numpy to multiply bool-values:
人们可以使用 numpy 的可能性来乘以布尔值:
(np.array(x)*np.array(y))
>> array([ True, False, False, False], dtype=bool)
Or do I overlook a special case?
还是我忽略了一个特殊情况?
回答by Manishankar Singh
In addition to what @Martijn Pieters has answered, I would just add the following code to explain and
and or
operations in action.
除了@Martijn Pieters 所回答的内容之外,我只想添加以下代码来解释and
和or
操作。
and
returns the first falsy value encountered else the last evaluated argument.
and
返回遇到的第一个假值,否则为最后一个评估参数。
Similarly or
returns the first truthy value encountered else the last evaluated argument.
类似地or
返回遇到的第一个真值,否则最后一个评估的参数。
nl1 = [3,3,3,3,0,0,0,0]
nl2 = [2,2,0,0,2,2,0,0]
nl3 = [1,0,1,0,1,0,1,0]
and_list = [a and b and c for a,b,c in zip(nl1,nl2,nl3)]
or_list = [a or b or c for a,b,c in zip(nl1,nl2,nl3)]
Values are
值是
and_list = [1, 0, 0, 0, 0, 0, 0, 0]
and_list = [1, 0, 0, 0, 0, 0, 0, 0]
or_list = [3, 3, 3, 3, 2, 2, 1, 0]
or_list = [3, 3, 3, 3, 2, 2, 1, 0]
回答by Marco Triches
Thanks for the answer @Martijn Pieters and @Tony. I dig into the timing of the various options we have to make the AND of two lists and I would like to share my results, because I found them interesting.
感谢@Martijn Pieters 和@Tony 的回答。我深入研究了我们必须对两个列表进行 AND 的各种选项的时间安排,我想分享我的结果,因为我发现它们很有趣。
Despite liking a lot the pythonic way [a and b for a,b in zip(x,y) ], turns out really slow. I compare with a integer product of arrays (1*(array of bool)) * (1*(array of bool)) and it turns out to be more than 10x faster
尽管非常喜欢pythonic方式[a和b for a,b in zip(x,y)],结果真的很慢。我与数组的整数乘积 (1*(array of bool)) * (1*(array of bool)) 进行比较,结果证明快 10 倍以上
import time
import numpy as np
array_to_filter = np.linspace(1,1000000,1000000) # 1 million of integers :-)
value_limit = 100
cycles = 100
# METHOD #1: [a and b for a,b in zip(x,y) ]
t0=time.clock()
for jj in range(cycles):
x = array_to_filter<np.max(array_to_filter)-value_limit # filter the values > MAX-value_limit
y = array_to_filter>value_limit # filter the values < value_limit
z= [a and b for a,b in zip(x,y) ] # AND
filtered = array_to_filter[z]
print('METHOD #1 = %.2f s' % ( (time.clock()-t0)))
# METHOD 1*(array of bool) AND 1*(array of bool)
t0=time.clock()
for jj in range(cycles):
x = 1*(array_to_filter<np.max(array_to_filter)-value_limit) # filter the values > MAX-value_limit
y = 1*(array_to_filter>value_limit) # filter the values < value_limit
z = x*y # AND
z = z.astype(bool) # convert back to array of bool
filtered = array_to_filter[z]
print('METHOD #2 = %.2f s' % ( (time.clock()-t0)))
The results are
结果是
METHOD #1 = 15.36 s
METHOD #2 = 1.85 s
The speed is almost affected equally by the size of the array or by the number of cycles.
I hope I helped someone code to be faster. :-)
速度几乎同样受数组大小或周期数的影响。
我希望我帮助某人编码更快。:-)
回答by AlwaysLearning
Here is a simple solution:
这是一个简单的解决方案:
np.logical_and(x,y)