Как проверить, пуст ли список?

2292
голосов

Например, если передано следующее:

a = []

Как проверить, нет ли a?

задан Ray Vega 10 сент. '08 в 9:20
источник

33 ответов

  • 1
  • 2
3298
голосов
if not a:
  print("List is empty")

Использование неявной логичности пустого списка довольно pythonic.

ответ дан Patrick 10 сент. '08 в 9:28
источник
751
голос

Питонический способ сделать это из PEP 8 style guide:

Для последовательностей (строки, списки, кортежи) используйте тот факт, что пустые последовательности являются ложными.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
ответ дан Harley Holcombe 10 сент. '08 в 13:33
источник
414
голосов

Я предпочитаю это явно:

if len(li) == 0:
    print('the list is empty')

Таким образом, на 100% ясно, что li - это последовательность (список), и мы хотим проверить ее размер. Моя проблема с if not li: ... заключается в том, что она дает ложное впечатление о том, что li является логической переменной.

ответ дан Jabba 05 сент. '11 в 3:30
источник
155
голосов

Другие люди, похоже, обобщают вопрос, выходящий за рамки списков, поэтому я подумал, что добавлю оговорку для другого типа последовательности, которую могут использовать многие люди, тем более, что это первый хит google для msgstr "пустой пул python".

Другие методы не работают для массивов numpy

Вам нужно быть осторожным с массивами numpy, потому что другие методы, которые отлично работают для list или других стандартных контейнеров, терпят неудачу для массивов numpy. Я объясняю, почему ниже, но вкратце, предпочтительный метод заключается в использовании size.

"Питонический" способ не работает: Часть 1

"pythonic" способ терпит неудачу с массивами numpy, потому что numpy пытается передать массив массиву из bool s, а if x пытается оценить все те bool сразу для какого-то совокупного значения истины, Но это не имеет никакого смысла, поэтому вы получаете ValueError:

>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

"Питонический" способ не работает: Часть 2

Но, по крайней мере, вышеприведенный случай говорит вам, что он не прошел. Если у вас массив numpy с ровно одним элементом, оператор if будет "работать" в том смысле, что вы не получите ошибку. Однако, если этот один элемент имеет значение 0 (или 0.0 или false,...), оператор if неверно приведет к false:

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

Но ясно, что x существует и не пусто! Этот результат не тот, который вам нужен.

Использование len может дать неожиданные результаты

Например,

len( numpy.zeros((1,0)) )

возвращает 1, хотя массив имеет нулевые элементы.

Путь numpythonic

Как объяснено в scipy FAQ, правильный метод во всех случаях, когда вы знаете, что у вас есть массив numpy, заключается в использовании if x.size

>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x

Если вы не уверены, может ли это быть list, массив numpy или что-то еще, вы могли бы объединить этот подход с ответ @dubiousjim дает чтобы убедиться, что для каждого типа используется правильный тест. Не очень "pythonic", но оказывается, что numpy намеренно сломал питоничность, по крайней мере, в этом смысле.

Если вам нужно сделать больше, чем просто проверить, является ли вход пустым, и вы используете другие функции numpy, такие как индексирование или математические операции, он, вероятно, более эффективен (и, конечно, более распространен), чтобы заставить ввод быть numpy массив. Есть несколько хороших функций для этого быстро - самое главное numpy.asarray. Это берет ваш вход, ничего не делает, если он уже является массивом, или переносит ваш ввод в массив, если он является списком, кортежем и т.д., И, возможно, преобразует его в выбранный dtype. Так что это очень быстро, когда это может быть, и это гарантирует, что вы просто догадываетесь, что ввод представляет собой массив numpy. Обычно мы просто используем одно и то же имя, так как преобразование в массив не будет возвращаться за пределы текущего scope:

x = numpy.asarray(x, dtype=numpy.double)

Это сделает проверку проверки x.size во всех случаях, которые я вижу на этой странице.

ответ дан Mike 21 февр. '12 в 19:48
источник
87
голосов

Пустой список сам по себе считается ложным при тестировании истинных значений (см. документация python):

a = []
if a:
     print "not empty"

@Daren Thomas

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

Ваш duckCollection должен реализовать __nonzero__ или __len__, поэтому if: будет работать без проблем.

ответ дан Peter Hoffmann 10 сент. '08 в 9:31
источник
68
голосов

Ответ Патрика (принят) прав: if not a: - это правильный способ сделать это. Ответ Harley Holcombe прав, что это в руководстве по стилю PEP 8. Но ни один из ответов не объясняет, почему хорошая идея следовать за идиомой - даже если вы лично найдете ее недостаточно явной или запутанной для пользователей Ruby или что-то еще.

Код Python и сообщество Python имеют очень сильные идиомы. После этих идиом ваш код легче читать для любого, кто имеет опыт работы на Python. И когда вы нарушаете эти идиомы, это сильный сигнал.

Истинно, что if not a: не выделяет пустые списки из None, или числовые 0, или пустые кортежи, или пустые созданные пользователем типы коллекций, или пустые созданные пользователем типы не-вполне коллекции, или одиночные -элементный массив NumPy, действующий как скаляры с ложными значениями и т.д. И иногда важно быть явным. И в этом случае вы знаете, о чем хотите быть явным, поэтому вы можете точно это проверить. Например, if not a and a is not None: означает "что-либо ложное, кроме None", а if len(a) != 0: означает "только пустые последовательности - и все, кроме последовательности, является ошибкой здесь" и т.д.). Помимо тестирования для того, что вы хотите проверить, это также сигнализирует читателю, что этот тест важен.

Но если у вас нет ничего, о чем нужно говорить, ничего, кроме if not a:, вводит в заблуждение читателя. Вы сигнализируете что-то важное, когда это не так. (Возможно, вы также делаете код менее гибким или медленным, или что-то еще, но это все менее важно.) И если вы обычно вводите в заблуждение читателя, как это, тогда, когда вам нужно сделать различие, это пройдет незамеченным, потому что вы были "плачущим волком" по всему вашему коду.

ответ дан abarnert 03 дек. '14 в 5:21
источник
52
голосов

Я видел это как предпочтительное, так как он также будет искать нулевой список:

if not a:
    print "The list is empty or null"
ответ дан hazzen 10 сент. '08 в 9:28
источник
41
голос

len() - это операция O (1) для списков, строк, диктов и наборов Python. Python внутренне отслеживает количество элементов в этих контейнерах.

JavaScript имеет аналогичное понятие правды/фальшивки.

ответ дан George V. Reilly 15 сент. '08 в 8:50
источник
33
голосов

Лучший способ проверить, пустой ли список

Например, если передано следующее:

a = []

Как проверить, является ли пустой?

Краткий ответ:

Поместите список в логический контекст (например, с помощью оператора if или while). Он проверит False, если он пуст, и True в противном случае. Например:

if not a:                           # do this!
    print('a is an empty list')

Обращение к власти

PEP 8, официальное руководство по стилю Python для кода Python в стандартной библиотеке Python утверждает:

Для последовательностей (строки, списки, кортежи) используйте тот факт, что пустые последовательности являются ложными.

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

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

Описание

Я часто вижу такой код от опытных программистов, новых для Python:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

И у пользователей ленивых языков может возникнуть соблазн сделать это:

if a == []:                         # Don't do this!
    print('a is an empty list')

Они верны на своих других языках. И это даже семантически корректно в Python.

Но мы считаем его не-Pythonic, потому что Python поддерживает эту семантику непосредственно в интерфейсе объектов списка с помощью логического принуждения.

Из docs (и обратите внимание на включение пустого списка []):

По умолчанию объект считается истинным, если его класс не определяет либо метод __bool__(), который возвращает метод False или __len__()который возвращает ноль при вызове с объектом. Вот большинство встроенных объектов, считанных false:

  • константы, определенные как ложные: None и False.
  • нуль любого числового типа: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • пустые последовательности и коллекции: '', (), [], {}, set(), range(0)

И документация datamodel:

object.__bool__(self)

Вызывается для реализации тестирования значений истинности и встроенной операции bool(); должен возвращать False или True. Когда этот метод не определен, __len__() вызывается, если он определен, и объект считается истинным, если его результат отличен от нуля. Если класс не определяет ни __len__()ни __bool__(), все его экземпляры считаются истинными.

и

object.__len__(self)

Вызывается для реализации встроенной функции len(). Должен возвращать длину объекта, целое число >= 0. Кроме того, объект, который не определяет метод __bool__() и метод __len__() возвращает ноль, считается логическим в булевом контексте.

Итак, вместо этого:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

или это:

if a == []:                     # Don't do this!
    print('a is an empty list')

Сделайте это:

if not a:
    print('a is an empty list')

Выполнение того, что Pythonic обычно окупается в производительности:

Оплачивается ли он? (Обратите внимание, что меньше времени для выполнения эквивалентной операции лучше:)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=10)) - min(timeit.repeat(lambda: [], repeat=10))
0.07626811624504626
>>> min(timeit.repeat(lambda: [] == [], repeat=10)) - min(timeit.repeat(lambda: [], repeat=10))
0.032089774729683995
>>> min(timeit.repeat(lambda: not [], repeat=10)) - min(timeit.repeat(lambda: [], repeat=10))
0.008945178240537643

Мы видим, что либо проверка длины с встроенной функцией len по сравнению с 0, либо проверка на пустой список намного менее эффективны, чем использование встроенного синтаксиса языка, как задокументировано.

Почему?

Для len(a) == 0 проверьте:

Первый Python должен проверить глобальные переменные, чтобы увидеть, будет ли затенена len.

Затем он должен вызвать функцию, загрузить 0 и выполнить сравнение равенства в Python (вместо C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

И для [] == [] он должен создать ненужный список, а затем снова выполнить операцию сравнения в виртуальной машине Python (в отличие от C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

Путь "Pythonic" намного проще и быстрее, так как длина списка кэшируется в заголовке экземпляра объекта:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

Доказательства из источника C и документации

PyVarObject

Это расширение PyObject, которое добавляет поле ob_size. Это используется только для объектов, которые имеют некоторое понятие длины. Этот тип не часто появляется в API Python/C. Он соответствует полям, определяемым расширением макроса PyObject_VAR_HEAD.

Из источника c в Include/listobject.h:

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

Мне понравилось исследовать это, и я трачу много времени на то, чтобы отучить свои ответы. Если вы думаете, что я оставляю что-то, пожалуйста, дайте мне знать в комментарии.

ответ дан Aaron Hall 20 авг. '17 в 6:50
источник
32
голосов

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

Я бы сказал, что самый пифонический способ - не проверять вообще, а просто обрабатывать список. Таким образом, он сделает правильные вещи, пустые или полные.

a = []

for item in a:
    <do something with item>

<rest of code>

Это позволяет использовать любое содержимое a, не требуя конкретной проверки на пустоту. Если a пуст, зависимый блок не будет выполняться, и интерпретатор перейдет к следующей строке.

Если вам действительно нужно проверить массив на пустоту, другие ответы достаточны.

ответ дан MrWonderful 06 окт. '15 в 22:25
источник
23
голосов

Я написал:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

который был проголосован -1. Я не уверен, что это потому, что читатели возражали против стратегии или думали, что ответ не был полезен, как представлено. Я буду притворяться, что это последнее, поскольку --- независимо от того, что считается "пифоническим" - это правильная стратегия. Если вы уже не исключили или готовы обрабатывать случаи, когда a, например, False, вам нужен тест более ограничительный, чем просто if not a:. Вы можете использовать что-то вроде этого:

if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff

первый тест в ответ на ответ @Mike, выше. Третья строка также может быть заменена на:

elif isinstance(a, (list, tuple)) and not a:

если вы хотите только принять экземпляры определенных типов (и их подтипы) или с помощью

elif isinstance(a, (list, tuple)) and not len(a):

Вы можете уйти без явной проверки типа, но только если окружающий контекст уже заверяет вас, что a - это значение типов, которые вы готовы обработать, или если вы уверены, что типы, которые вы используете не подготовленные к обработке, собираются поднять ошибки (например, a TypeError, если вы вызываете len на значение, для которого оно undefined), которое вы готовы обработать. В общем, "питонические" соглашения, похоже, идут последним путем. Сожмите его, как утку, и дайте ему поднять DuckError, если он не знает, как крякать. Вы все равно должны думать о том, какие предположения вы делаете, и действительно ли случаи, когда вы не готовы правильно обращаться, будут ошибаться в правильных местах. Массивы Numpy - хороший пример, когда только слепо полагаясь на len, или логический тип может не делать именно то, что вы ожидаете.

ответ дан dubiousjim 31 мая '12 в 17:35
источник
23
голосов

Python очень единообразен в отношении лечения пустоты. Учитывая следующее:

a = []

.
.
.

if a:
   print("List is not empty.")
else:
   print("List is empty.")

Вы просто проверяете список a оператором if, чтобы узнать, пуст ли он. Из того, что я прочитал и чему его научили, это "Pythonic" способ увидеть, что список или кортеж пуст.

ответ дан octopusgrabbus 02 июня '12 в 18:40
источник
16
голосов

Из документации по тестированию значений истинности:

Все значения, отличные от перечисленных здесь, считаются True

  • None
  • False
  • ноль любого числового типа, например, 0, 0.0, 0j.
  • любая пустая последовательность, например '', (), [].
  • любое пустое отображение, например {}.
  • экземпляров пользовательских классов, если класс определяет метод __bool__() или __len__(), когда этот метод возвращает целое число 0 или значение bool False.

Как видно, пустой список [] является ложным, поэтому выполнение того, что было бы сделано с булевым значением, звучит наиболее эффективно:

if not a:
    print('"a" is empty!')
ответ дан Sнаđошƒаӽ 01 янв. '16 в 21:18
источник
13
голосов

Вот несколько способов проверки пустого списка:

a = [] #the list

1) Довольно простой pythonic путь:

if not a:
    print("a is empty")

В Python пустые контейнеры, такие как списки, кортежи, наборы, dicts, переменные и т.д. рассматриваются как False. Можно просто рассматривать список как предикат (возвращающий логическое значение). И значение True указывает, что оно не пустое.

2). Явным образом: используя len(), чтобы найти длину и проверить, соответствует ли она 0:

if len(a) == 0:
    print("a is empty")

3) Или сравнивая его с анонимным пустым списком:

if a == []:
    print("a is empty")

4) Еще один глупый способ - использовать exception и iter():

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")
ответ дан Inconnu 28 нояб. '16 в 17:18
источник
8
голосов

Я предпочитаю следующее:

if a == []:
   print "The list is empty."

Считывается, и вам не нужно беспокоиться о вызове функции типа len() для итерации по переменной. Хотя я не совсем уверен, что примечание BigO о чем-то вроде этого... но Python так невероятно быстро, я сомневаюсь, что это имело бы значение, если a не было гигантским.

ответ дан verix 10 сент. '08 в 9:43
источник
7
голосов

некоторые методы, которые я использую:

if not a:
    print "list is empty"

if not bool(a):
    print "list is empty"

if len(a) == 0:
    print "list is empty"
ответ дан Hackaholic 27 окт. '14 в 3:35
источник
6
голосов

Конечно, есть и

print a or "List is empty"

ответ дан spedy 16 февр. '16 в 2:18
источник
5
голосов

Вы также можете сделать:

if len(a_list):
    print "it not empty"
ответ дан AndrewSmiley 02 дек. '17 в 22:48
4
голосов
def list_test (L):
    if   L is None  : print 'list is None'
    elif not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test(None)
list_test([])
list_test([1,2,3])

Иногда бывает полезно протестировать None и для пустоты отдельно, поскольку это два разных состояния. Приведенный выше код производит следующий вывод:

list is None 
list is empty 
list has 3 elements

Хотя ничего не стоит, что None является ложным. Поэтому, если вы не хотите отделять тест на None -ness, вам не нужно это делать.

def list_test2 (L):
    if not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test2(None)
list_test2([])
list_test2([1,2,3])

производит ожидаемый

list is empty
list is empty
list has 3 elements
ответ дан Tagar 14 апр. '16 в 0:55
источник
4
голосов
>>> 'Not Empty' if a else 'Empty'


См. Примеры

>>> a = []
>>> 'Not Empty' if a else 'Empty'
'Empty'


>>> a = [0, 1, 2, 3]
>>> 'Not Empty' if a else 'Empty'
'Not Empty'
ответ дан Shameem 02 дек. '17 в 22:48
2
голосов
a = []

# First way
if a:
    print 'yes'
else:
    print 'no'

# Second way
if len(a) != 0:
    print 'yes'
else:
    print 'no'
ответ дан Rajiv Sharma 02 дек. '17 в 22:48
2
голосов

Try:

if list:
    #Not empty
else:
    #Empty

if выполняет первый оператор, если list не является пустой последовательностью, None, False или 0

ответ дан An Epic Person 02 дек. '17 в 22:48
2
голосов

Другой способ, который не указан в предыдущих ответах и ​​не может быть "лучшим способом", чтобы проверить, является ли list пустым или нет, используется специальный метод list.__sizeof__(), который возвращает int, которые представляют размер текущего списка в памяти в байтах.

Пример:

Пустой список

a = [] # Or a = list()
size = a.__sizeof__()
print(size)
# With 64bit OS it will output: 40
>>> 20

Нет пустого списка

a = [1]
b = list('1')
size_a = a.__sizeof__()
size_b = b.__sizeof__()
print(size_a)
print(size_b)
# With 64bit OS it will output:
# 48
# 72
>>> 24
>>> 36

Как мы видим, sizeof a none empty list превосходит sizeof для empty list.

Итак, мы можем проверить, пуст или нет список, например, следующим образом:

# For 64 bit OS:
# is_empty = lambda x: x.__sizeof__() is 40
is_empty = lambda x: x.__sizeof__() is 20
a = [] # Or: a = list()
b = [1]
c = list('1')
print("a is empty:", is_empty(a))
print("b is empty:", is_empty(b))
print("c is empty:", is_empty(c))

>>> a is empty: True
>>> b is empty: False
>>> c is empty: False

Bonus:

sizeof пустых dict, str и tuple:

bonus = [{}, '', ()]
for k in bonus:
    print(k.__sizeof__())
# With 64 bit OS it will output:
# 264
# 49
# 24
>>> 132  # size of an empty dict
>>> 25   # size of an empty str
>>> 12   # size of an empty tuple
ответ дан Chiheb Nexus 02 дек. '17 в 22:48
2
голосов

Любая пустая последовательность оценивает до False в Python:

>>> lst = []
>>> bool(lst)
False
>>> not lst
True
>>> 

Это основано на аналогичном ответе для словарей.

  • любая пустая последовательность, например, '',(), [].

  • любое пустое отображение, например {}.

ответ дан Tarek Kalaji 02 дек. '17 в 22:48
1
голос

Проверьте длину списка, если он равен нулю, список пуст

>>> if len(list) == 0:
    #the list is empty
ответ дан shad 02 дек. '17 в 22:48
0
голосов

Список Python считается False, когда он пуст, и True, когда он не пуст. Следующее будет работать довольно хорошо

    if seq:print('List has items') 
    if not seq:print('List does not have items')

Также

    bool(seq) #will return true if the list has items and false if the list does not.

Это также будет работать для любых последовательностей python.

ответ дан user3444876 02 дек. '17 в 22:48
0
голосов

Просто используйте is_empty() или создайте функцию: -

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

Он может использоваться для любой структуры данных, такой как список, кортежи, словарь и многое другое. Этим вы можете называть это много раз, используя только is_empty(any_structure).

ответ дан Vineet Jain 26 авг. '17 в 22:04
источник
0
голосов

просто:

>>> list = []
>>> len(list)
    0

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

>>> def empty(list):
>>>    return "Empty" if not len(list) else "Not empty"

>>> empty(a)
    'Empty'

>>> a.append(0)

>>> empty(a)
    'Not empty'
ответ дан Flavio Milan 02 дек. '17 в 22:47
0
голосов

Будучи вдохновленным решением @dubiousjim, я предлагаю использовать дополнительную общую проверку того, является ли это чем-то итерируемым

import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)

Примечание: строка считается итерируемой. - добавьте and not isinstance(a,(str,unicode)), если вы хотите исключить пустую строку

Тест:

>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True
ответ дан AndreyS Scherbakov 29 марта '17 в 5:58
источник
0
голосов

Вы даже можете попробовать использовать bool() следующим образом

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

Мне нравится, что для проверки список пуст или нет.

Очень удобно и полезно.

ответ дан Sunil Lulla 13 сент. '16 в 14:53
источник
  • 1
  • 2

Другие вопросы по меткам