2014-11-20 11 views
1

Я хотел бы выбрать конкретный элемент, который удовлетворяет условию из (очень длинного) списка. В моем конкретном случае каждый элемент списка является классом, и условие, что я хочу, например, item.id == 1.Выберите элемент, который удовлетворяет условию

Я начал с

[item for item in collection if item.id == 1] 

, но я не хочу пересечь весь список, потому что я уверен, что есть только один элемент, который удовлетворяет условию.

Другой вариант

def check(collection): 
    for item in collection: 
     if item.id == 1: 
      return item 

Есть ли более эффективный способ? У Python 3 есть встроенная функция для этого? Другим вариантом может быть предварительная обработка списка, чтобы получить словарь, например.

{item.id : item for item in collection} 
+0

Не могли бы вы добавить класс в другой список, когда item.id изменяется до 1? – kezzos

+0

Нет, я не могу id. У меня есть список таких элементов, и мне нужно выбрать конкретный. Если я добавлю каждый элемент в новый список, у меня будут 'len (collectcion)' новые списки с 1 элементом каждый – meto

ответ

6

Вы можете использовать generator expression и next() function:

item = next((item for item in collection if item.id == 1), None) 

Это будет найти первый соответствующий элемент в сборе, или вернуть None, если нет совпадения. Он не будет перебирать и оценивать больше, чем требуется, чтобы найти этот один элемент.

Однако, если вам нужно сделать, это много, создавая отображение только один раз, то запрашивая, что каждый раз, когда будет более эффективным:

mapping = {item.id: item for item in collection} 
item = mapping.get(1) 

, как я ограничу зацикливание только один раз, затем используйте функцию поиска O (1). Это компромисс между памятью и скоростью.

1

Чтобы получить первый элемент, который удовлетворяет условию, используйте next(), как указано в the ninja's answer.

Чтобы получить элемент, который удовлетворяет условию и проверить, что это только одна такая, я использую следующую функцию:

def single(seq): 
    """Checks that the sequence has a single element and returns it.""" 
    """Analogous to .Net LINQ's Single()""" 
    if hasattr(seq,"__len__"): 
     assert len(seq)==1 
     return seq[0] 
    else: 
     i=iter(seq) 
     try: value=i.next() 
     except StopIteration: raise AssertionError() 
     try: i.next() 
     except StopIteration: return value 
     else: raise AssertionError() 
Смежные вопросы