Как проверить, пуст ли список?
- 1
- 2
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
Вы должны быть осторожны с массивами 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
работать во всех случаях, которые я вижу на этой странице.
Лучший способ проверить, пустой ли список
Например, если передано следующее:
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')
Выполнение того, что 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 и документации
Это расширение
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 или значение boolFalse
.
Как видно, пустой список []
является ложным, поэтому выполнение того, что было бы сделано с булевым значением, звучит наиболее эффективно:
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")
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")
мы могли бы использовать простой, если еще:
item_list=[]
if len(item_list) == 0:
print("list is empty")
else:
print("list is 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()
- 1
- 2
Посмотрите другие вопросы по меткам python list is-empty или Задайте вопрос