3

単純なリスト内包表記に基づく:

yay = [ i for i in a if a[i] ]
nay = [ i for i in a if not a[i] ]

yayと の両方の値を一度に割り当てる方法があるかどうか疑問に思っていnayます (つまり、条件付きのヒットとミス)。

このように見えるもの

( yay , nay ) = ...

私は読みやすさと速度について興味がありました (2 つのリスト内包表記が、どちらかのリストに追加される単一の for ループよりも約 5% 高速であることに少し驚きました)。


アップデート:

元の例は、辞書で「true」と「false」の値のキーのリストを取得することでした...

a = {i: i >= 50 for i in range(100)}

yay = [k for k, v in a.items() if v]
nay = [k for k, v in a.items() if not v]
4

6 に答える 6

7

ここでの通常の解決策は、リスト内包表記を使用するという考えにとらわれないことです。forループを使用するだけです:

yay, nay = [], []
for i in a:
    if somecondition(i):
        yay.append(i)
    else:
        nay.append(i)

これを頻繁に行う場合は、単純にコードを関数に移動します。

def yesno(seq, cond):
    yay, nay = [], []
    for i in seq:
        if cond(i):
            yay.append(i)
        else:
            nay.append(i)
    return yay, nay

yay, nay = yesno(a, lambda x: a[x])

コメントは、これがリスト内包表記よりも遅いことを示唆しています。ラムダとして条件を渡すことは必然的に大きな打撃を与えることになるでしょう。それについて多くのことを行うことはできないと思いますが、パフォーマンスの打撃の一部はおそらくappendメソッドを調べることから来ており、改善することができます:

def yesno(seq, cond):
    yay, nay = [], []
    yes, no = yay.append, nay.append
    for i in seq:
        if cond(i):
            yes(i)
        else:
            no(i)
    return yay, nay

それが大きな違いを生むかどうかはわかりませんが、時間を計るのは興味深いかもしれません。

コメントで @martineau は、ジェネレーターを使用して で消費することを提案していany()ます。ここにそれを含めますがany、イテレーターを使用する itertools レシピに置き換えます。

def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

そして、次のように書くことができます:

yay, nay = [], []
consume((yay if a[i] else nay).append(i) for i in a)
于 2013-02-11T19:10:07.053 に答える
4

あなたのやり方はより読みやすく、提案されたアプローチであるべきだと私はまだ言いますが、いずれにせよ、代替手段を探しているなら、 itertools からの解決策を期待できます

>>> from itertools import compress, imap
>>> from operator import not_
>>> yay, nay = compress(a,a.values()), compress(a, imap(not_,a.values()))
于 2013-02-11T19:17:15.950 に答える
0

これは、次のような方法で実行できます。

yay, nay = zip(*[(k, None) if v else (None, k) for k, v in a.items()])
yay, nay = filter(None, yay), filter(None, nay)

それがより速いかどうかについては...多分巨大なリストのために。そうでなければ、それはおそらく問題にならないでしょう。

当然、Noneがリスト内の値である場合は、それを別の番兵と交換し、でIDチェックを行う必要がありますfilter()

于 2013-02-11T19:05:58.457 に答える
0

dict内包表記を使用できる場合もありますが、リスト内包表記を使用して要求したことを実行することはできないと確信しています。データがソートされている、またはソートできると仮定すると**私はおそらくを使用しますitertools.groupby

results = itertools.groupby(sorted_a, bool)

*資格:OK、Lattywareの回答は、できることを示していますNone、iterableの各メンバーの値を持つタプルも生成します。無駄なIMOです。私はそれを考慮していなかったと告白しますが、私はそれを考慮しなかったことを恥じません。

**並べ替え:グループ化されたのと同じキーで並べ替える必要があります。

于 2013-02-11T19:06:09.557 に答える
0

編集

まあ、私はダンカンのものとかなり同じ解決策を書きました。だから私は自分が書いたものを削除し、私が最良の解決策であると考えるものを許可し、1つのダンカンの解決策とマルティノーの提案を混ぜ合わせます(any()の使用はlist()またはリストの使用よりもはるかに好ましいように見えます私が書いたものとしての理解;非常に良いアイデアany() 、それはconsume() IMOをインポートする複雑さよりも優れています)

def disting(L):
        dust,right = [],[]
        dustapp = dust.append
        rightapp = right.append
        any(rightapp(x) if x else dustapp(x) for x in L)
        return right,dust

for seq in ((10,None,'a',0,None,45,'qada',False,True,0,456),
            [False,0,None,104,True,str,'',88,'AA',__name__]):
    yay,nay = disting(seq)     
    print 'seq == %r\nyay == %r\nnay == %r' % (seq,yay,nay)
    print '---------------------------------------'

結果

seq == (10, None, 'a', 0, None, 45, 'qada', False, True, 0, 456)
yay == [10, 'a', 45, 'qada', True, 456]
nay == [None, 0, None, False, 0]
---------------------------------------
seq == [False, 0, None, 104, True, <type 'str'>, '', 88, 'AA', '__main__']
yay == [104, True, <type 'str'>, 88, 'AA', '__main__']
nay == [False, 0, None, '']
---------------------------------------

ちなみに、any()rightapp(x)を使用すると、dustapp(x)Noneが返されるため機能します。TrueまたはTrueと同等のものが返される場合、 any()内の反復は停止します!

于 2013-02-12T18:57:44.997 に答える
0

きれいではありませんが、次の行で何かを行うことができます。

nay = []
yay = [foo for foo in foos if condition or nay.append(foo)]

orこれは、オペレータの短絡を利用しています。

于 2013-02-11T22:23:17.273 に答える