Подтвердить что ты не робот

Найти объект своим членом внутри списка в python

позволяет использовать следующий простой объект:

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

то у меня есть список с некоторыми такими объектами:

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

Есть ли встроенная функция, где я могу получить все Mocks с возрастом, т.е. 30? Конечно, я могу повторить их и сравнить их возрасты, но что-то вроде

find(myList, age=30)

было бы неплохо. Есть что-то в этом роде?

4b9b3361

Ответ 1

Вы можете предварительно проиндексировать их -

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]

Изменить: изображение стоит тысячи слов:

enter image description here

Ось X - это число Mocks в myList, ось Y - время выполнения в секундах.

  • красные точки - это метод @dcrooney filter()
  • синие точки - это понимание @marshall.ward.
  • зеленые точки, скрывающиеся за осью X, являются моим индексом; -)

Ответ 2

Вы можете попробовать filter():

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

Это приведет к возврату списка только с теми объектами, которые удовлетворяют выражению лямбда.

Ответ 3

Список понятий может выбрать их:

new_list = [x for x in myList if x.age == 30]

Ответ 4

Пояснения к спискам - это почти всегда более быстрый способ делать эти вещи (в два раза быстрее), хотя, как упоминалось ранее, индексирование происходит даже быстрее, если вы обеспокоены скоростью.

~$ 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)]