22

次の単純なオブジェクトを想定します。

class Mock:
    def __init__(self, name, age):
        self.name = name
        self.age = age

次に、次のようなオブジェクトのリストがあります。

myList = [Mock("Dan", 34), Mock("Jack", 30), Mock("Oli", 23)...]

年齢が 30 歳のすべてのモックを取得できる組み込み機能はありますか? もちろん、私はそれらを反復して年齢を比較することができますが、

find(myList, age=30)

いいだろう。そのようなものはありますか?

4

4 に答える 4

36

それらを事前にインデックス化したい場合があります-

from collections import defaultdict

class Mock(object):
    age_index = defaultdict(list)

    def __init__(self, name, age):
        self.name = name
        self.age = age
        Mock.age_index[age].append(self)

    @classmethod
    def find_by_age(cls, age):
        return Mock.age_index[age]

編集:写真は千の言葉に値する:

ここに画像の説明を入力

X 軸は myList 内のモックの数、Y 軸は秒単位のランタイムです。

  • 赤い点は @dcrooney の filter() メソッドです
  • 青い点は @marshall.ward のリスト内包表記です
  • X 軸の後ろに隠れている緑色の点は私のインデックスです ;-)
于 2012-06-01T23:44:32.920 に答える
35

filter()を試すことができます:

filter(lambda x: x.age == 30, myList)

これにより、ラムダ式を満たすオブジェクトのみのリストが返されます。

于 2012-06-01T23:39:21.557 に答える
21

リスト内包表記はこれらを拾うことができます:

new_list = [x for x in myList if x.age == 30]
于 2012-06-01T23:40:30.973 に答える
5

リスト内包表記は、ほとんどの場合、これらのことを行うためのより高速な方法です (ここでは 2 倍高速です)。

~$ python -mtimeit -s"from mock import myList" "filter(lambda x: x.age==21, myList)"
1000000 loops, best of 3: 1.34 usec per loop
~$ python -mtimeit -s"from mock import myList" "[x for x in myList if x.age==21]"
1000000 loops, best of 3: 0.63 usec per loop

現在のディレクトリのファイルの場合mock.py:

class Mock:
    def __init__(self, name, age):
        self.name = name
        self.age = age

myList = [Mock('Tom', 20), Mock('Dick', 21), Mock('Harry', 21), Mock('John', 22)]
于 2012-06-02T00:50:51.890 に答える