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

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

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

a = []

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

4b9b3361

Ответ 1

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

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

Ответ 2

Пифонический способ сделать это из руководства по стилю PEP 8 (где " Да" означает "рекомендуется" и " Нет" означает "не рекомендуется"):

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

Yes: if not seq:
     if seq:

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

"Питонический" способ не работает с массивами NumPy, поскольку NumPy пытается преобразовать массив в массив из bool, а 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 способ

Как объясняется в FAQ по SciPy, правильный метод во всех случаях, когда вы знаете, что у вас есть массив 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 преднамеренно нарушил pythonicity по крайней мере в этом смысле.

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

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

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

Ответ 5

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

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

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 поддерживает эту семантику непосредственно в интерфейсе объектов списка с помощью логического принуждения.

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

По умолчанию объект считается истинным, если его класс не определяет __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=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

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

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

Мы видим, что либо проверка длины с встроенной функцией 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

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

Ответ 6

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

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

@Daren Thomas

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

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

Ответ 7

Ответ Патрика (принят) прав: 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:, вводит в заблуждение читателя. Вы сигнализируете что-то важное, когда это не так. (Возможно, вы также делаете код менее гибким или медленным, или что-то еще, но это все менее важно.) И если вы обычно вводите в заблуждение читателя, как это, тогда, когда вам нужно сделать различие, это пройдет незамеченным, потому что вы были "плачущим волком" по всему вашему коду.

Ответ 8

Я видел ниже как предпочтительный:

if not a:
    print("The list is empty or null")

Ответ 9

Зачем вообще проверять?

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

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

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

Ответ 11

Я написал:

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, или логический тип может не делать именно то, что вы ожидаете.

Ответ 12

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

a = []

.
.
.

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

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

Ответ 13

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

if not a:
    print "list is empty"


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

Ответ 14

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

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

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

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

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

Ответ 15

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

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")

Ответ 16

Способ 1 (предпочтительный):

if not a : 
   print ("Empty") 

Способ 2:

if len(a) == 0 :
   print( "Empty" )

Способ 3:

if a == [] :
  print ("Empty")

Ответ 17

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

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

Ответ 18

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

Ответ 19

Было дано много ответов, и многие из них довольно хороши. Я просто хотел добавить, что проверка

not a

Также сойдет за None и другие типы пустых структур. Если вы действительно хотите проверить пустой список, вы можете сделать это:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

Ответ 20

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

print a or "List is empty"

Ответ 21

мы могли бы использовать простой, если еще:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")

Ответ 22

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

if len(a_list):
    print "it not empty"

Ответ 23

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

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

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

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

Ответ 24

>>> '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'

Ответ 25

Будучи вдохновленным решением @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

Ответ 26

Другим простым способом может быть

a = []
if len(a) == 0:
  print("Empty")
else:
  print(" Not empty")

Ответ 27

Начиная с python3 вы можете использовать

a == []

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

РЕДАКТИРОВАТЬ: Это работает с python2.7 тоже..

Я не уверен, почему есть так много сложных ответов. Это довольно ясно и просто

Ответ 28

Вы можете проверить, равна ли длина массива нулю (или нет). Если длина массива равна нулю, то он пуст. попробуйте следующее:

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

Ответ 29

Простой способ проверки длины равен нулю.

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

Ответ 30

print('not empty' if a else 'empty')

немного более практично:

a.pop() if a else None

и самая короткая версия:

if a: a.pop()