Например, если передано следующее:
a = []
Как проверить, нет ли a
?
Например, если передано следующее:
a = []
Как проверить, нет ли a
?
if not a:
print("List is empty")
Использование неявной логики пустого list
довольно питонно.
Пифонический способ сделать это из руководства по стилю PEP 8 (где " Да" означает "рекомендуется" и " Нет" означает "не рекомендуется"):
Для последовательностей (строки, списки, кортежи) используйте тот факт, что пустые последовательности являются ложными.
Yes: if not seq: if seq: No: 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" и аналогичных запросов, плюс другие люди, кажется, обобщают вопрос, выходящий за рамки просто списков, поэтому я решил добавить предостережение для последовательности другого типа, которую многие люди может использовать.
Вы должны быть осторожны с массивами NumPy, потому что другие методы, которые отлично работают для list
или других стандартных контейнеров, не работают для массивов NumPy. Ниже я объясню, почему, но вкратце, предпочтительным методом является использование size
.
"Питонический" способ не работает с массивами 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()
Но, по крайней мере, приведенный выше случай говорит вам, что это не удалось. Если у вас есть массив 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, хотя в массиве нет элементов.
Как объясняется в 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
работать во всех случаях, которые я вижу на этой странице.
Лучший способ проверить, пустой ли список
Например, если передано следующее:
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:
Вызывается для реализации тестирования ценности истины и встроенной операции
bool()
; должен возвращатьFalse
илиTrue
. Когда этот метод не определен,__len__()
, если он определен, и объект считается истинным, если его результат отличен от нуля. Если класс не определяет ни__len__()
ни__bool__()
, все его экземпляры считаются истинными.
а также
Вызывается для реализации встроенной функции
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')
Оплачивается ли это? (Обратите внимание, что меньше времени для выполнения эквивалентной операции лучше :)
>>> 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
Это расширение
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
Мне понравилось исследовать это, и я много времени уделяю своим ответам. Если вы думаете, что я оставляю что-то, пожалуйста, дайте мне знать в комментарии.
Пустой список сам по себе считается ложным при тестировании истинных значений (см. документация python):
a = []
if a:
print "not empty"
@Daren Thomas
EDIT: Еще одна точка против тестирования пустой список: False: как насчет полиморфизм? Вы не должны зависеть от список - список. Он должен просто шарлатан как утка - как ты собираешься получить утку "False", если у него нет элементов?
Ваш duckCollection должен реализовать __nonzero__
или __len__
, поэтому if: будет работать без проблем.
Ответ Патрика (принят) прав: 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:
, вводит в заблуждение читателя. Вы сигнализируете что-то важное, когда это не так. (Возможно, вы также делаете код менее гибким или медленным, или что-то еще, но это все менее важно.) И если вы обычно вводите в заблуждение читателя, как это, тогда, когда вам нужно сделать различие, это пройдет незамеченным, потому что вы были "плачущим волком" по всему вашему коду.
Я видел ниже как предпочтительный:
if not a:
print("The list is empty or null")
Никто, кажется, не поставил вопрос о необходимости проверить список в первую очередь. Поскольку вы не предоставили никакого дополнительного контекста, я могу представить, что вам может не понадобиться делать эту проверку в первую очередь, но они не знакомы с обработкой списка в Python.
Я бы сказал, что самый пифонический способ - не проверять вообще, а просто обрабатывать список. Таким образом, он будет делать правильные вещи, будь то пустой или полный.
a = []
for item in a:
<do something with item>
<rest of code>
Это имеет преимущество обработки любого содержимого a, не требуя специальной проверки на пустоту. Если a пуст, зависимый блок не будет выполняться, и интерпретатор перейдет к следующей строке.
Если вам действительно нужно проверить массив на пустоту, других ответов достаточно.
len()
- это операция O (1) для списков, строк, диктов и наборов Python. 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
на значение, для которого оно undefined), которое вы готовы обработать. В общем, "питонические" соглашения, похоже, идут последним путем. Сожмите его, как утку, и дайте ему поднять DuckError, если он не знает, как крякать. Вы все равно должны думать о том, какие предположения вы делаете, и действительно ли случаи, когда вы не готовы правильно обращаться, будут ошибаться в правильных местах. Массивы Numpy - хороший пример, когда только слепо полагаясь на len
, или логический тип может не делать именно то, что вы ожидаете.
Python очень единообразен в отношении лечения пустоты. Учитывая следующее:
a = []
.
.
.
if a:
print("List is not empty.")
else:
print("List is empty.")
Вы просто проверяете список a оператором if, чтобы узнать, пуст ли он. Из того, что я прочитал и чему его научили, это "Pythonic" способ увидеть, что список или кортеж пуст.
Некоторые методы, которые я использую:
if not a:
print "list is empty"
if len(a) == 0:
print "list is empty"
Из документации по тестированию значений истинности:
Все значения, отличные от перечисленных здесь, считаются True
None
False
0
, 0.0
, 0j
.''
, ()
, []
.{}
.__bool__()
или __len__()
, когда этот метод возвращает целое число 0 или значение bool False
.Как видно, пустой список []
является ложным, поэтому выполнение того, что было бы сделано с булевым значением, звучит наиболее эффективно:
if not a:
print('"a" is empty!')
Вот несколько способов проверки пустого списка:
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")
Способ 1 (предпочтительный):
if not a :
print ("Empty")
Способ 2:
if len(a) == 0 :
print( "Empty" )
Способ 3:
if a == [] :
print ("Empty")
Я предпочитаю следующее:
if a == []:
print "The list is 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
-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
Было дано много ответов, и многие из них довольно хороши. Я просто хотел добавить, что проверка
not a
Также сойдет за None
и другие типы пустых структур. Если вы действительно хотите проверить пустой список, вы можете сделать это:
if isinstance(a, list) and len(a)==0:
print("Received an empty list")
Конечно, есть и
print a or "List is empty"
мы могли бы использовать простой, если еще:
item_list=[]
if len(item_list) == 0:
print("list is empty")
else:
print("list is not empty")
Вы также можете сделать:
if len(a_list):
print "it not empty"
Вы даже можете попробовать использовать bool() следующим образом
a = [1,2,3];
print bool(a); # it will return True
a = [];
print bool(a); # it will return False
Мне нравится, что для проверки список пуст или нет.
Очень удобно и полезно.
>>> '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'
Будучи вдохновленным решением @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
Другим простым способом может быть
a = []
if len(a) == 0:
print("Empty")
else:
print(" Not empty")
Начиная с python3 вы можете использовать
a == []
проверить, если список пуст
РЕДАКТИРОВАТЬ: Это работает с python2.7 тоже..
Я не уверен, почему есть так много сложных ответов. Это довольно ясно и просто
Вы можете проверить, равна ли длина массива нулю (или нет). Если длина массива равна нулю, то он пуст. попробуйте следующее:
a = []
if len(a)==0 : print "List is empty"
Простой способ проверки длины равен нулю.
if len(a) == 0:
print("a is empty")
print('not empty' if a else 'empty')
немного более практично:
a.pop() if a else None
и самая короткая версия:
if a: a.pop()