Предположим, я создаю простой класс для работы, аналогичный структуре в стиле C, просто для хранения элементов данных. Я пытаюсь понять, как искать в списке объектов объекты с атрибутом, равным определенному значению. Ниже приведен простой пример, иллюстрирующий то, что я пытаюсь сделать.
Например:
class Data:
pass
myList = []
for i in range(20):
data = Data()
data.n = i
data.n_squared = i * i
myList.append(data)
Как мне выполнить поиск в списке myList, чтобы определить, содержит ли он элемент с n == 5?
Я гуглил и искал документы Python, и я думаю, что смогу сделать это с пониманием списка, но я не уверен. Я мог бы добавить, что мне, кстати, приходится использовать Python 2.4.3, поэтому какие-либо новые функции gee-whiz 2.6 или 3.x мне недоступны.
Ответы:
Вы можете получить список всех совпадающих элементов с пониманием списка:
[x for x in myList if x.n == 30] # list of all elements with .n==30
Если вы просто хотите определить, содержит ли список какой-либо элемент, который соответствует, и сделать это (относительно) эффективно, вы можете сделать
def contains(list, filter): for x in list: if filter(x): return True return False if contains(myList, lambda x: x.n == 3) # True if any element has .n==3 # do stuff
источник
Простой, элегантный и мощный:
Выражение генератора в сочетании со встроенным… (Python 2.5+)
any(x for x in mylist if x.n == 10)
Использует
any()
встроенный Python , который определяется следующим образом:def any(iterable): for element in iterable: if element: return True return False
источник
any(x for x in mylist if x['n'] == 10)
но это хорошая идеяДля полноты картины давайте не будем забывать о простейшей вещи, которая могла бы работать:
for i in list: if i.n == 5: # do something with it print "YAY! Found one!"
источник
[x for x in myList if x.n == 30] # list of all matches [x.n_squared for x in myList if x.n == 30] # property of matches any(x.n == 30 for x in myList) # if there is any matches [i for i,x in enumerate(myList) if x.n == 30] # indices of all matches def first(iterable, default=None): for item in iterable: return item return default first(x for x in myList if x.n == 30) # the first match, if any
источник
filter(lambda x: x.n == 5, myList)
источник
lambda
s.Вы можете использовать
in
для поиска элемента в коллекции и понимание списка для извлечения интересующего вас поля. Это (работает для списков, наборов, кортежей и всего, что определяет__contains__
или__getitem__
).if 5 in [data.n for data in myList]: print "Found it"
Смотрите также:
источник
Вы должны добавить в свой класс метод
__eq__
и__hash__
методData
, он может проверить__dict__
, равны ли атрибуты (одинаковые свойства), а затем, равны ли их значения.Если вы это сделали, вы можете использовать
test = Data() test.n = 5 found = test in myList
В
in
ключевых словах проверяет,test
находится вmyList
.Если вам нужно только
n
свойство,Data
вы можете использовать:class Data(object): __slots__ = ['n'] def __init__(self, n): self.n = n def __eq__(self, other): if not isinstance(other, Data): return False if self.n != other.n: return False return True def __hash__(self): return self.n myList = [ Data(1), Data(2), Data(3) ] Data(2) in myList #==> True Data(5) in myList #==> False
источник
Подумайте об использовании словаря:
myDict = {} for i in range(20): myDict[i] = i * i print(5 in myDict)
источник
Другой способ сделать это - использовать функцию next ().
matched_obj = next(x for x in list if x.n == 10)
источник