Вопрос

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

a = []

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

Это было полезно?

Решение

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

Используя неявную логичность пустого list довольно питонистный.

Другие советы

Питонический способ сделать это - из Руководство по стилю PEP 8 (где ДА означает “рекомендуемый” и НЕТ означает “не рекомендуется”):

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

ДА: if not seq:
     if seq:

НЕТ:  if len(seq):
     if not len(seq):

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

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

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

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

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

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

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

"Питонический" способ терпит неудачу с массивами NumPy, потому что NumPy пытается преобразовать массив в массив bools, и if x пытается оценить все эти bools сразу для получения какого-то совокупного значения истинности.Но в этом нет никакого смысла, так что вы получаете 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, даже если массив содержит ноль элементов.

Нумпифонный способ

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

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

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

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

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

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

a = []

Как мне проверить, является ли a пустым?

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

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

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

Апелляция к Авторитету

БОДРОСТЬ ДУХА 8, официальное руководство по стилю Python для кода Python в стандартной библиотеке Python, утверждает:

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

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.

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

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

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

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

И документация по модели данных:

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 находится в тени.

Затем он должен вызвать функцию load 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

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

>>> 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 в Включить/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

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

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

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

@Дарен Томас

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

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

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

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

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

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

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

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

JavaScript имеет аналогичное понятие истинности / лживости.

Я написал:

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 от значения, для которого оно не определено), с которым вы готовы справиться.В общем, "питонические" соглашения, похоже, идут этим последним путем.Сожмите его, как утку, и пусть он поднимет утиную тревогу, если он не умеет крякать.Тебе все равно придется подумай однако о том, какие предположения вы делаете, и действительно ли случаи, с которыми вы не готовы справиться должным образом, будут содержать ошибки в нужных местах.Массивы Numpy являются хорошим примером, когда просто слепо полагаются на len или логическое приведение типов может делать не совсем то, что вы ожидаете.

От Документация о тестировании истинностных значений:

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

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

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

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

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

a = [] #the list

1) Довольно простой питонический способ:

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

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

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

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

if not a : 
   print ("Empty") 

Способ 2 :

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

Способ 3:

if a == [] :
  print ("Empty")
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-несс, ты не обязана этого делать.

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

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

not a

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

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

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

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

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

Мне нравится этот способ проверки того, пуст список или нет.

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

Простой способ - проверить, что длина равна нулю.

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

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

a.pop() if a else None

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

a == []

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

Редактировать :Это работает и с python2.7..

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

мы могли бы использовать простое if else:

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

Просто используйте 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).

Чтобы проверить, пуст список или нет, вы можете воспользоваться двумя следующими способами.Но помните, что нам следует избегать явной проверки последовательности или списка (это less pythonic способ):

def Enquiry(list1): 
    if len(list1) == 0: 
        return 0
    else: 
        return 1

# ––––––––––––––––––––––––––––––––

list1 = [] 

if Enquiry(list1): 
    print ("The list isn't empty") 
else: 
    print("The list is Empty") 

# Result: "The list is Empty".

Второй способ - это more pythonic один.Этот метод является неявным способом проверки и гораздо более предпочтителен, чем предыдущий.

def Enquiry(list1): 
    if not list1: 
        return 1
    else: 
        return 0

# ––––––––––––––––––––––––––––––––

list1 = [] 

if Enquiry(list1): 
    print ("The list is Empty") 
else: 
    print ("The list isn't empty") 

# Result: "The list is Empty"

Надеюсь, это поможет.

Проверьте, есть ли: len(list) == 0 ВОЗВРАТ: True

Если вы хотите проверить, пуст ли список;

l = []
if l:
    # do your stuff.

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

l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.

Однако это будет справедливо для пустого списка.

def empty_list(lst):
    if len(lst) ==0:
        return false
    else:
        return all(bool(x) for x in l)

Теперь вы можете использовать:

if empty_list(lst):
    # do your stuff.

Истинное значение пустого списка равно False принимая во внимание, что для непустого списка это True.

То, что привело меня сюда, - это особый пример использования:Я действительно хотел функция чтобы сказать мне, пуст список или нет.Я хотел избежать написания своей собственной функции или использования здесь лямбда-выражения (потому что казалось, что это должно быть достаточно просто):

    foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))

И, конечно, есть очень естественный способ сделать это:

    foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))

Конечно, делайте нет использование bool в if (т.е., if bool(L):) потому что это подразумевается.Но для случаев, когда "не пусто" явно необходимо как функция, bool это лучший выбор.

Дурацкий способ использования pop и try except оговорка (не рекомендуется):

a = []
try:
    a.pop()
    print('list isn\'t empty')
except:
    print('list is empty')

Выходной сигнал:

list is empty

Неофициальный подход :

 a = []
 try:
  print(a[-1])
 except IndexError:
  print("List is empty")
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top