我有两个清单:
X = [True,False]
Y = [True,True]
我正在尝试将 X[0] 与 Y[0] 和 X[1] 与 Y[1] 进行比较。
我试过了
in [7]: X and Y
Out[7]: [True, True]
但我期待的结果是 [True,False]。
我应该做什么?
我有两个清单:
X = [True,False]
Y = [True,True]
我正在尝试将 X[0] 与 Y[0] 和 X[1] 与 Y[1] 进行比较。
我试过了
in [7]: X and Y
Out[7]: [True, True]
但我期待的结果是 [True,False]。
我应该做什么?
这是使用 的绝佳机会map
,因为and
可以用内置函数表示:
import operator
X = [True,False]
Y = [True,True]
map(operator.and_, X,Y)
#=> [True, False]
你得到你所做的行为的原因是and
对操作数执行操作,就好像它们已bool
应用于它们一样。所有非空列表都True
在布尔上下文中计算。
至于“列表理解总是更好”这一点:不,不是。等效的列表推导是:
[x and y for x, y in zip(X, Y)]
它必须构建一个中间对象(列表或生成器,取决于 python 版本),并且仍然需要读者知道做什么zip
,就像知道的一样map
。它也可能稍微慢一些(因为 map + 内置函数很快 - 这一切都发生在 C 层,本质上)。事实上,timeit
显示izip
更快(见下文),但我真的认为可读性点更重要;如果性能真的很重要,您可能还会看到不同的结果。
>>> timeit.timeit('map(operator.and_, X,Y)', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000)
1.0160579681396484
>>> timeit.timeit('[x and y for x, y in zip(X, Y)]', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000)
1.3570780754089355
>>> timeit.timeit('[x and y for x, y in itertools.izip(X, Y)]', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000)
0.965054988861084
也就是说,如果您需要任意数量的列表,则需要all
在列表推导中使用(或直接结合使用izip
);andand_
在技术上是按位的 and,因此请注意,如果使用bool
.
这是一个all
版本:
import itertools
map(all,itertools.izip(X,Y,Z))
所有非空列表都True
在布尔上下文中求值,并and
求值为它求值的最后一个表达式(Y
在这种情况下),这就是你得到结果的原因。你想要这样的东西:
[x and y for x, y in zip(X, Y)]
假设您有任意一组列表:
A=[True, False, False]
B=[True, True, False]
C=[3,0,0]
现在编写一些看起来有点像itertools.izip但允许添加函数的东西:
def elements(*iterables, **kwds):
func=kwds.get('func', None)
iterables=map(iter, iterables)
while iterables:
t=tuple(map(next, iterables))
if func is not None:
yield func(t)
else:
yield t
现在添加将返回逻辑结果的函数F(A[0],B[0],C[0]...)
。例如,它们每个都执行描述的功能:
def ands(elements):
''' logical 'and' for all the elements'''
return all(elements)
def ors(elements):
''' logical 'or' for all the elements'''
return any(elements)
def bitand(elements):
''' bitwise 'and' for all the elements'''
return reduce(operator.and_,elements)
然后只需调用该函数:
print list(elements(A,B,C,func=ands))
# [True, False, False]
或者为你的具体例子:
print list(elements([True,False],[True,True],func=ands))
# [True, False]
或者直接使用all
:
print list(elements([True,False],[True,True],func=all))
# [True, False]