Используя понимание списка для нахождения 1 элемента в списке? - PullRequest
1 голос
/ 05 марта 2019

У меня есть быстрый вопрос относительно лучших практик для Python.Я видел, где функции фильтра лямбда + использовались над пониманием списка, но я хотел знать, есть ли более простой способ найти определенный элемент в списке без необходимости генерировать и повторять его по всему списку.

Используя библиотеку AWS boto3, я запрашиваю различные функции get_x (), используя понимание списка:

[i['domainName'] for i in domain_names['items'] if re.search(r'\b'+domain_name, i['domainName'])].pop()

[i['id'] for i in usage_plans['items'] if i['name']==f'{self.service}Usage'].pop()

Если нетнайденный элемент, IndexError будет перехвачен и передан обратно пользователю.Так как это относится к лямбда-функции AWS, меня беспокоит масштабируемость и биллинг во время выполнения для этой функции.

Должен ли я продолжать использовать списочное понимание так, как я это делаю, или есть лучший способ

1 Ответ

4 голосов
/ 05 марта 2019

Если вы хотите избежать итерации по всему списку, вы можете использовать генераторное понимание вместо списка.Например:

next(i for i in range(0, 2**1000) if i % 2 == 1)

Итерация по всему диапазону займет некоторое время, но при использовании понимания генератора это происходит мгновенно.

Обратите внимание, что если он не находит предмет, вы получаете StopIteration исключение вместо IndexError.Вы действительно должны поймать это и обернуть его в другое исключение, потому что паразит StopIteration, распространяющийся по стеку, может вызвать странное поведение.

Обтекание StopIteration выглядит следующим образом:

>>> try:
...   next(i for i in range(0, 100) if i % 2 == 3 )
... except StopIteration:
...   raise IndexError("Couldn't find item")
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
IndexError: Couldn't find item

Обратите внимание, что вместо значения StopIteration:

>>> print(next((i for i in range(0, 100) if i % 2 == 3), None))
None
вы можете задать для next значение по умолчанию, которое будет возвращаться по умолчанию.
...