Получить первый элемент из итерируемого, который соответствует условию - PullRequest
238 голосов
/ 02 марта 2010

Я хотел бы получить первый элемент из списка, соответствующего условию. Важно, чтобы полученный метод не обрабатывал весь список, который может быть довольно большим. Например, следующая функция является адекватной:

def first(the_iterable, condition = lambda x: True):
    for i in the_iterable:
        if condition(i):
            return i

Эту функцию можно использовать примерно так:

>>> first(range(10))
0
>>> first(range(10), lambda i: i > 3)
4

Однако я не могу придумать хорошую встроенную / однострочную, чтобы позволить мне это сделать. Я не особенно хочу копировать эту функцию, если мне не нужно. Есть ли встроенный способ получить первый элемент, соответствующий условию?

Ответы [ 14 ]

0 голосов
/ 25 января 2019

Вы также можете использовать функцию argwhere в Numpy. Например:

i) Найдите первое «l» в «helloworld»:

import numpy as np
l = list("helloworld") # Create list
i = np.argwhere(np.array(l)=="l") # i = array([[2],[3],[8]])
index_of_first = i.min()

ii) Найти первое случайное число> 0,1

import numpy as np
r = np.random.rand(50) # Create random numbers
i = np.argwhere(r>0.1)
index_of_first = i.min()

iii) Найти последнее случайное число> 0,1

import numpy as np
r = np.random.rand(50) # Create random numbers
i = np.argwhere(r>0.1)
index_of_last = i.max()
0 голосов
/ 29 апреля 2016

В Python 3:

a = (None, False, 0, 1)
assert next(filter(None, a)) == 1

В Python 2.6:

a = (None, False, 0, 1)
assert next(iter(filter(None, a))) == 1

РЕДАКТИРОВАТЬ: Я думал, что это было очевидно, но, видимо, нет: вместо None вы можете передать функцию (или lambda) с проверкой на условие:

a = [2,3,4,5,6,7,8]
assert next(filter(lambda x: x%2, a)) == 3
0 голосов
/ 20 апреля 2012

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

(lambda x:x[0] if x else None)(list(y for y in ITERABLE if CONDITION))

(Если ни один элемент не соответствует, вы получите None, а не StopIteration исключение.)

0 голосов
/ 02 марта 2010

Oneliner:

thefirst = [i for i in range(10) if i > 3][0]

Если вы не уверены, что какой-либо элемент будет действительным в соответствии с критериями, вы должны заключить его в try/except, поскольку [0] может повысить IndexError.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...