元素方式'和'用于python中的列表?

时间:2013-09-16 19:13:47

标签: python

我有两个清单:

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]。

我该怎么办?

3 个答案:

答案 0 :(得分:14)

这是使用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 + builtin函数很快 - 它本质上都发生在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结合使用);并且and_在技术上是按位的,因此请注意,如果使用bool以外的数字类型,可能会产生时髦的结果。

以下是all版本:

import itertools
map(all,itertools.izip(X,Y,Z))

答案 1 :(得分:9)

所有非空列表在布尔上下文中计算为Trueand计算到它评估的最后一个表达式(在这种情况下为Y),这就是为什么你得到的结果你这样做。你想要这样的东西:

[x and y for x, y in zip(X, Y)]

答案 2 :(得分:0)

假设您有任意一组列表:

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]