4

最初の要素として「b」を含むサブリストから整数値を取得したい (b はリストに 1 回だけ表示されます)

これらの2つの方法が頭に浮かびました:

foo = [["a", 5], ["b", 10], ["c", 100]]

y = filter(lambda x: x[0] == "b", foo)
print y[0][1]

z = [foo[i][1] for i in range(len(foo)) if foo[i][0] == "b"] 
print z[0]

どちらも機能します。(ランタイムに関して)2つのいずれかが望ましいですか、さらに優れた3番目の方法はありますか?

4

2 に答える 2

11

リストが非常に小さい場合、両者の間に大きな違いはありません。入力リストが大きくなる可能性がある場合は、さらに悪い問題があります。最初の要素で停止する可能性がある一方で、リスト全体を反復処理しています。これは for ループで実現できますが、内包表記のようなステートメントを使用する場合は、ジェネレーター式を使用します。

# like list comprehensions but with () instead of []
gen = (b for a, b in foo if a == 'b')
my_element = next(gen)

または単に:

my_element = next(b for a, b in foo if a == 'b')

ジェネレーター式について詳しく知りたい場合は、PEP 289を参照してください。


ジェネレーターとイテレーターを使用しても、複数の選択肢があることに注意してください。

# Python 3:
my_element = next(filter(lambda x: x[0] == 'b', foo))

# Python 2:
from itertools import ifilter
my_element = next(ifilter(lambda (x, y): x == 'b', foo))

私は個人的にこれが好きではなく、読みにくいのでお勧めしません。これは実際には最初のスニペットよりも遅いことがわかりましたが、より一般的filter()には、ジェネレーター式の代わりに使用した方が、いくつかの特別なケースでは高速になる可能性があります。

いずれにせよ、コードのベンチマークが必要な場合は、モジュールを使用するtimeitことをお勧めします。

于 2013-03-13T11:38:48.037 に答える
4

これはDavidEの答え(私はそれを計時しました)より遅いですが、単純さの利点があります:

z = dict(foo)['b']

もちろん、キーはすべてハッシュ可能であると想定していますが、文字列であれば問題ありません。複数のルックアップを実行する必要がある場合、これは間違いなく進むべき方法です(dictに変換するのは1回だけにしてください)。

于 2013-03-13T11:46:27.760 に答える