Python: Найти в списке - PullRequest
475 голосов
/ 03 марта 2012

Я сталкивался с этим:

item = someSortOfSelection()
if item in myList:
    doMySpecialFunction(item)

но иногда он не работает со всеми моими элементами, как если бы они не были распознаны в списке (когда это список строк).

Является ли это наиболее «питоническим» способом поиска предмета в списке: if x in l:?

Ответы [ 11 ]

996 голосов
/ 03 марта 2012

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

Что касается вашего второго вопроса: на самом деле есть нескольковозможные способы «поиска» вещей в списках.

Проверка, находится ли что-то внутри

Это описанный вами вариант использования: проверка, находится ли что-то внутри списка или нет.Как вы знаете, вы можете использовать оператор in для этого:

3 in [1, 2, 3] # => True

Фильтрация коллекции

То есть поиск всех элементов в последовательности, которые удовлетворяют определенному условию.Для этого вы можете использовать списочные выражения или выражения генератора:

matches = [x for x in lst if fulfills_some_condition(x)]
matches = (x for x in lst if x > 6)

Последний вернет generator , который вы можете представить как некий ленивый список, который будет создан, как толькоВы повторяете это.Кстати, первый в точности эквивалентен

matches = filter(fulfills_some_condition, lst)

в Python 2. Здесь вы можете увидеть функции высшего порядка в работе.В Python 3 filter возвращает не список, а объект, похожий на генератор.

Поиск первого вхождения

Если вы хотите только первое, что соответствует условию (новы еще не знаете, что это такое), можно использовать цикл for (возможно, также с помощью предложения else, которое не очень хорошо известно).Вы также можете использовать

next(x for x in lst if ...)

, который вернет первое совпадение или поднимет StopIteration, если ничего не найдено.В качестве альтернативы вы можете использовать

next((x for x in lst if ...), [default value])

Поиск местоположения элемента

Для списков есть также метод index, который иногда может быть полезен, если вы хотите знать где определенный элемент находится в списке:

[1,2,3].index(2) # => 1
[1,2,3].index(4) # => ValueError

Однако учтите, что если у вас есть дубликаты, .index всегда возвращает самый низкий индекс: ......

[1,2,3,2].index(2) # => 1

Если есть дубликаты и вам нужны все индексы, вы можете использовать enumerate() вместо:

[i for i,x in enumerate([1,2,3,2]) if x==2] # => [1, 3]
161 голосов
/ 24 апреля 2012

Если вы хотите найти один элемент или None использовать значение по умолчанию в next, оно не повысит StopIteration, если элемент не найден в списке:

first_or_default = next((x for x in lst if ...), None)
14 голосов
/ 04 декабря 2015

Хотя ответ от Никласа Б. довольно всеобъемлющий, когда мы хотим найти элемент в списке, иногда бывает полезно получить его индекс:

next((i for i, x in enumerate(lst) if [condition on x]), [default value])
7 голосов
/ 07 января 2018

Поиск первого вхождения

Рецепт для этого есть в itertools:

def first_true(iterable, default=False, pred=None):
    """Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item
    for which pred(item) is true.

    """
    # first_true([a,b,c], x) --> a or b or c or x
    # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
    return next(filter(pred, iterable), default)

Например, следующий код находит первое нечетное число всписок:

>>> first_true([2,3,4,5], None, lambda x: x%2==1)
3  
3 голосов
/ 04 сентября 2018

Другая альтернатива: вы можете проверить, есть ли элемент в списке с помощью if item in list:, но это порядок O (n). Если вы имеете дело с большими списками элементов, и все, что вам нужно знать, это то, является ли что-то членом вашего списка, вы можете сначала преобразовать список в набор и воспользоваться преимуществом поиска по постоянному времени :

my_set = set(my_list)
if item in my_set:  # much faster on average than using a list
    # do something

Не будет правильным решением в каждом случае, но в некоторых случаях это может повысить производительность.

Обратите внимание, что создание набора с помощью set(my_list) также является O (n), поэтому, если вам нужно сделать это только один раз, то сделать это не быстрее. Если вам необходимо повторно проверять членство, тогда это будет O (1) для каждого поиска после создания этого начального набора.

2 голосов
/ 02 января 2019

Вместо использования list.index(x), который возвращает индекс x, если он найден в списке, или возвращает сообщение #ValueError, если x не найден, вы можете использовать list.count(x), который возвращает количество вхождений x в список(проверка того, что x действительно находится в списке) или он возвращает 0 в противном случае (при отсутствии x).Самое замечательное в count() в том, что он не нарушает ваш код и не требует от вас исключения, когда x не найден

1 голос
/ 19 января 2019

Определение и использование

метод count() возвращает количество элементов с указанным значением.

Синтаксис

list.count(value)

пример:

fruits = ['apple', 'banana', 'cherry']

x = fruits.count("cherry")

Пример вопроса:

item = someSortOfSelection()

if myList.count(item) >= 1 :

    doMySpecialFunction(item)
1 голос
/ 02 августа 2018
list = [10, 20, 30, 40, 50]
n = int(input("\nEnter a Number to search from the list : "))

if n in list :
    print("\nMatch found")  
else :
    print("\nMatch not found")
0 голосов
/ 09 апреля 2018

Например, если вы хотите найти индекс всех элементов больше 30:

your_list = [11,22,23,44,55]
filter(lambda x:your_list[x]>30,range(len(your_list)))

#result: [3,4]
0 голосов
/ 23 января 2018

Вы можете использовать один из двух возможных поисков при работе со списком строк:

  1. , если элемент списка равен элементу ('example' находится в [ 'Один', 'пример', 'два']):

    if item in your_list: some_function_on_true()

    'ex' в ['one', 'ex', 'two'] => True

    'ex_1' в ['one', 'ex', 'two'] => False

  2. если элемент списка равен как элемент ('ex' находится в ['one,' example ',' two '] или' example_1 'находится в [ 'Один', 'пример', 'два']):

    matches = [el for el in your_list if item in el]

    или

    matches = [el for el in your_list if el in item]

    , затем просто отметьте len(matches) или прочитайте их, если необходимо.

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