Раньше я делал это примерно так
a = None
for x in list:
if pred(x):
a = x
Очевидно что это не удобно. Как это обойти я подсмотрел здесь (там описано гораздо больше вариантов, но все они плохо работают с случаем когда ничего не найдено)
Итак делаем функцию find (которая должна бы быть в стандартной библиотеке языка)
def find(f, seq):
"""Return first item in sequence where f(item) == True."""
for item in seq:
if f(item):
return item
Дальше поиск прост
a = find(lambda x: x.id == 5, values) #will find value with id == 5 or None if nothing found
Стоит отметить что в 2.6 версии эта проблема решена и все гораздо проще (спасибо @ mishok13 за пример)
next((x for x in seq if pred(x)), None)
или для нашего примера
next((x for x in values if x.id == 5), None)
Какие есть еще более изящные варианты?
5 комментариев:
как вариант:
>>> some = [1,2,3,4,5]
>>> func = lambda x: x == 3
>>> filter(func, some)
[3]
>>> func2 = lambda x: x == 100
>>> filter(func2, some)
[]
>>> some = [1,2,3,4,5]
>>> [ x for x in some if x==3]
Комментаторы упустили основною мысль -- нужен или первый найденный обьект (один) или некий другой обьект.
Вот рецепт:
>>> seq = range(10)
>>> ([x for x in seq if x == 3] or [42])[0]
3
>>> ([x for x in seq if x == 13] or [42])[0]
42
Для любителей filter, тоже самое:
>>> (filter(lambda x: x == 3, seq) or [42])[0]
3
>>> (filter(lambda x: x == 13, seq) or [42])[0]
42
Но всё таки, лучше использовать builtin next, как я и советовал. Имплементация на питоне элементарна.
вопрос значит правильно ставить надо. list comprehension IMHO самый что ни на есть питоновский way to go. остальное - детали.
угу, у меня тоже такая функция написана.
Отправить комментарий