5

私は2つのリストを持っています:

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] でした。

私は何をすべきですか?

4

3 に答える 3

16

は組み込み関数で表すことができる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組み合わせて使用​​する) 必要があります。izipandand_は技術的にはビット単位の and であるため、 以外の数値型を使用すると、おかしな結果になる可能性があることに注意してboolください。

ここにallバージョンがあります:

import itertools
map(all,itertools.izip(X,Y,Z))
于 2013-09-16T19:17:03.653 に答える
9

空でないすべてのリストTrueは、ブール コンテキストでand評価され、最後に評価された式 (Yこの場合) に評価されます。これが、実行した結果を取得する理由です。次のようなものが必要です。

[x and y for x, y in zip(X, Y)]
于 2013-09-16T19:15:41.270 に答える
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]
于 2013-09-16T21:18:59.613 に答える