簡體   English   中英

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

[英]Element-wise 'and' for lists in python?

我有兩個清單:

X = [True,False]
Y = [True,True]

我試圖將X [0]與Y [0]和X [1]與Y [1]進行比較。

我試過了

in [7]: X and Y
Out[7]: [True, True]

但我期待的結果是[真,假]。

我該怎么辦?

這是使用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))

所有非空列表評估為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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM