0

次のようなタプルのコレクションであるデータ構造があります。

things = ( (123, 1, "Floogle"), (154, 33, "Blurgle"), (156, 55, "Blarg") )

1番目と3番目の要素は、それぞれコレクションに固有です。

私がやりたいのは、3番目の値を参照して特定のタプルを取得することです。例:

>>> my_thing = things.get( value(3) == "Blurgle" )
(154, 33, "Blurgle")

各値を1つずつチェックするループを作成するよりも良い方法があるはずです!

4

3 に答える 3

4

あなたが示すように、ループ(またはリスト内包表記やgenexpのような100%同等のもの)は、実際には、外部レベルの構造がタプルである場合の唯一のアプローチです-タプルは、意図的な設計により、非常に軽量なコンテナであり、実際にはメソッドはほとんどありません (インデックス作成、ループなどを実装するために必要ないくつかの特別なメソッドだけです;-)。

超高速の検索は、タプルではなく辞書の特徴です。「3番目の要素の値」を、求めるサブタプル(またはメインタプルのインデックス)にマッピングする辞書を(メイン構造として、または補助構造として)持つことはできませんか?これは 1 つのループで構築でき、必要な数の高速検索を提供できます。

ループすることを選択した場合、Brian のコメントによる genexp とそれに対する私の返信は読みやすく、平均して listcomp よりも 2 倍高速です (ループの半分しか行わないため)。

my_thing = next(item for item in things if item[2] == "Blurgle")

これは、「[2]サブアイテムがBlurgleに等しいものの次のアイテム」とスムーズに読みます(最初から開始しているため、見つけた「次の」アイテムが「最初」になります-そして、あなたの場合、のみ適切な方)。

述語を満たすアイテムがない場合をカバーする必要がある場合はnext、2 番目の引数を渡すことができます (必要に応じて返されます)。それ以外の場合 (私のスニペットのように 2 番目の引数はありません)述語を満たすアイテムはありません-どちらの動作もあなたが望むものかもしれません(ケースが発生することは決してないと言っているように、問題の発生は予期しないエラーになるため、例外は特定のアプリケーションに適しているように見えます)。

于 2009-06-26T05:04:52.893 に答える
1

リストであり、3番目の要素が一意であることがわかっている場合things、リスト内包はどうでしょうか。

>> my_thing = [x for x in things if x[2]=="Blurgle"][0]

内部的には、すべての値を調べて個別にチェックすると思います。それが気に入らない場合は、my_things構造を変更してadictにし、最初または3番目の値をキーとして使用するのはどうでしょうか。

于 2009-06-26T04:54:31.410 に答える
1

このタイプの検索を複数回行う必要がある場合は、物事を things_dict に一度変換してみませんか。後で検索するのが簡単で高速になります

things = ( (123, 1, "Floogle"), (154, 33, "Blurgle"), (156, 55, "Blarg") )

things_dict = {}
for t in things:
    things_dict[t[2]] = t

print things_dict['Blarg']
于 2009-06-26T05:58:35.210 に答える