Разница между двумя «содержит» операции для списков Python - PullRequest
3 голосов
/ 20 октября 2011

Я довольно новичок в python и обнаружил, что мне нужно запросить список о том, содержит ли он определенный элемент.
Большинство сообщений, которые я видел на различных веб-сайтах (включая этот похожий вопрос стекопотока ), предлагали что-то вроде

for i in list
    if i == thingIAmLookingFor
        return True

Однако я также нашел на одном форуме, что

if thingIAmLookingFor in list
    # do work

работает.

Мне интересно, является ли метод if thing in list сокращенным для метода for i in list или он реализован по-другому.

Я также хотел бы, чтобы, если либо, более предпочтительным.

Ответы [ 4 ]

4 голосов
/ 20 октября 2011

В вашем простом примере конечно лучше использовать in.

Однако ... в вопрос, на который вы ссылаетесь , in не работает (по крайней мере, не напрямую), потому что OP не хочет найти объект, равный чему-либо, но объект, чей атрибут n равен чему-то.

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

if 5 in (data.n for data in myList):
    print "Found it"

Но это вряд ли намного лучше, чем другие подходы, такие как этот, использующий any:

if any(data.n == 5 for data in myList):
    print "Found it"
2 голосов
/ 20 октября 2011

формат «если х в вещи:» настоятельно предпочтителен не только потому, что он требует меньше кода, но также работает с другими типами данных и (мне) легче читать.

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

1 голос
/ 20 октября 2011
for i in list
    if i == thingIAmLookingFor
        return True

Вышесказанное - ужасный способ проверить, существует ли предмет в коллекции. Он возвращает True из функции, поэтому, если вам нужен тест как часть некоторого кода, вам нужно переместить его в отдельную служебную функцию или добавить thingWasFound = False перед циклом и установить его True в операторе if (и затем разрыв), каждая из которых представляет собой несколько строк стандартного выражения для простого выражения.

Кроме того, если вы просто используете thingIAmLookingFor in list, этот может выполняться более эффективно, делая меньше операций на уровне Python (для этого потребуется выполнить те же операции, но, возможно, в C, например list) это встроенный тип). Но что еще более важно, если list действительно связан с какой-либо другой коллекцией, такой как набор или словарь, thingIAmLookingFor in list будет использовать механизм поиска хеша, который поддерживают такие типы, и будет намного более эффективным, при использовании * Цикл 1017 * заставит Python проходить каждый элемент по очереди.

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

1 голос
/ 20 октября 2011

if thing in somelist является предпочтительным и быстрым способом.

Под капотом это использование оператора in переводится в somelist.__contains__(thing), реализация которого эквивалентна: any((x is thing or x == thing) for x in somelist).

Запишите условие проверки идентичности, а затем равенство.

...