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

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

a = []

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

10.09.2008 06:20:11
27 ОТВЕТОВ
РЕШЕНИЕ
if not a:
  print("List is empty")

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

5379
26.11.2019 12:19:41
Играя адвоката дьявола. Я не понимаю, почему эта идиома считается питонической. «Явное лучше, чем неявное», верно? Эта проверка не кажется очень явной в отношении того, что проверяется.
James McMahon 22.11.2011 06:14:02
@JamesMcMahon - это компромисс между ясностью и гибкостью типов. как правило, «быть явным» означает не делать «волшебные» вещи. с другой стороны, «типизирование утки» означает работу с более общими интерфейсами, а не явную проверку типов. таким образом, что-то вроде if a == []форсирования определенного типа ( () == []есть False). здесь, по общему мнению, выигрывает типизация утки (фактически, говорят, что __nonzero__это интерфейс для проверки пустоты docs.python.org/reference/datamodel.html#object.__nonzero__ )
andrew cooke 31.05.2012 14:50:08
Этот метод не работает с массивами numpy ... так что я думаю, что len (a) == 0 предпочтительнее как с точки зрения "утиной типизации", так и с точки зрения неявности.
Mr.WorshipMe 20.03.2019 18:01:33
Канонический способ узнать, является ли массив в C пустым, - разыменовать первый элемент и посмотреть, является ли он нулевым, предполагая, что массив имеет нулевое окончание. В противном случае сравнение его длины с нулем совершенно неэффективно, если массив имеет значительный размер. Кроме того, обычно вы не выделяете память для пустого массива (указатель остается нулевым), поэтому нет смысла пытаться получить его длину. Я не говорю, что len (a) == 0 не очень хороший способ сделать это, он просто не кричит мне «C», когда я это вижу.
sleblanc 2.04.2019 23:55:42
@BrennenSprimont, если он не завершен нулем, то вы уже знаете длину, хранится ли она в отдельной переменной или ваш массив обернут в некоторый контейнер, который отслеживает длину. C ++, Java, C # имеют такие контейнеры и эффективно реализуют метод "length". С не имеет такой вещи , вы должны свернуть свои собственные. Статически распределенные массивы C - это просто указатели на область памяти, в которой гарантированно достаточно места для хранения запрошенного вами объема данных. В C нет ничего, что позволило бы вам узнать, сколько вы уже заполнили это пространство.
sleblanc 14.04.2019 16:03:18

Пустой список сам по себе считается ложным в тестировании истинного значения (см. Документацию по Python ):

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

@ Дарен Томас

РЕДАКТИРОВАТЬ: Еще одно замечание против проверки пустого списка как False: Как насчет полиморфизма? Вы не должны зависеть от списка, являющегося списком. Он должен просто крякать, как утка - как вы собираетесь заставить свой duckCollection крякать «Ложь», когда в нем нет элементов?

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

137
6.09.2014 01:29:54
Странно, как [] == Falseбудет оцениваться, хотя False
information_interchange 14.10.2019 03:34:00
@information_interchange Если вы хотите явно проверить правильность значения, используйте bool(). bool([]) == Falseбудет оценивать, Trueкак ожидалось.
augurar 20.10.2019 07:29:08

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

if a == []:
   print "The list is empty."
20
5.01.2019 04:25:35
Это будет медленнее, так как вы создаете дополнительный пустой список без необходимости.
Carl Meyer 10.09.2008 13:42:00
это менее читабельно чем if not a:и ломается легче. Пожалуйста, не делай этого.
devsnd 12.11.2012 11:23:26
Есть хороший пункт, сделанный ранее () == [], также равный ложному. Хотя мне нравится, как эта реализация читает if not a:все случаи, если вы определенно ожидаете список, тогда вашего примера должно быть достаточно.
A Star 16.03.2019 21:03:31

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

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

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
1146
26.03.2018 17:17:27
Второй способ кажется более подходящим, если вы хотите seqуказать, что ожидается, что это какой-то объект типа списка.
BallpointBen 10.05.2018 18:44:42
@BallpointBen, который, как утверждают сторонники Pythonism, должен быть неявным в том, как именуется переменная, насколько это возможно
axolotl 14.07.2018 05:35:39
@BallpointBen попробуйте использовать подсказку типа Python для обозначения переменной. Это было введено в 3.5.
Boris 4.01.2019 23:46:56
numpy нарушил эту идиому ... seq = numpy.array ([1,2,3]), за которым следует, если нет, seq вызывает исключение "ValueError: Значение истинности массива с более чем одним элементом является неоднозначным. Используйте a.any () или a.all () "
Mr.WorshipMe 20.03.2019 18:03:33
Несмотря на все Pythonic защитники, я с @BallpointBen в том, что, если вы ошибочно написали seq = [0]как seq = 0, len(seq)поможет вам поймать ошибку. Человеку свойственно ошибаться. Так и программист.
aafulei 26.09.2019 02:34:34

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

У JavaScript есть похожее понятие истина / ложь .

66
14.06.2012 01:03:57

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

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

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

749
9.09.2017 04:04:11
Проверка того, равна ли длина списка нулю, а не просто проверка, является ли список ложным, уродлива и неуместна. Любой, кто знаком с Python, вообще не будет думать, что liэто глупость, и ему все равно. Если это важно, вы должны добавить комментарий, а не больше кода.
Carl Smith 9.07.2013 13:43:53
Это кажется излишне точным тестом, который часто медленнее и всегда менее читабелен ИМХО. Вместо того, чтобы проверять размер чего-либо пустого, почему бы просто не проверить, пусто ли оно?
John B 23.06.2014 14:46:46
В любом случае, причина того, что это плохо (а нарушение идиом в языке с сильными идиомами, такими как Python, вообще плохо), заключается в том, что он сообщает читателю, что вы по какой-то причине специально проверяете длину (например, потому что вы хотите Noneили 0поднять исключение, а не проходить). Итак, когда вы делаете это без причины, что это вводит в заблуждении, и это также означает , что , когда ваш код делает потребность сделать различие, различие невидимо , потому что вы «кричал волк» во всем остальном источника.
abarnert 3.12.2014 02:05:52
Я думаю, что это просто излишне удлиняет код. Иначе, почему бы не быть еще более "явным" с if bool(len(li) == 0) is True:?
augurar 5.01.2015 19:40:05
@Jabba во многих случаях будет O (1) (в тех случаях, когда вы работаете со встроенными типами данных), но вы просто не можете на это полагаться. Возможно, вы работаете с пользовательским типом данных, у которого нет этого свойства. Вы можете также решить добавить этот пользовательский тип данных позже, после того, как вы уже написали этот код.
ralokt 19.11.2015 13:04:15

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

Другие методы не работают для массивов 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, даже если массив содержит ноль элементов.

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проверку работоспособной во всех случаях, которые я вижу на этой странице.

320
25.06.2019 15:43:10
Стоит отметить, что это не недостаток в Python, а преднамеренный разрыв контракта numpy- numpyбиблиотека с очень конкретным случаем использования, и она имеет другое «естественное» определение того, что истинность в массиве для Стандарт Python для контейнеров. Имеет смысл оптимизировать для этого случая способом, который pathlibиспользуется /для объединения путей вместо +- это нестандартно, но имеет смысл в контексте.
Gareth Latty 16.02.2015 20:47:12
Согласовано. Моя точка зрения заключается в том, что важно помнить, что numpy сделал выбор, чтобы сломать типизацию утки как для самых распространенных, так if xи для len(x)идиом - и иногда этот разрыв может быть очень трудно обнаружить и отладить.
Mike 16.02.2015 21:21:02
Я не знаю, для меня, если метод с именем len (x) не возвращает длину массива из-за предположений, его имя плохо спроектировано.
Dalton 20.08.2015 19:54:14
Этот вопрос не имеет ничего общего с массивами numpy
pppery 31.07.2017 18:58:37
@ppperry Да, первоначальный вопрос был не о массивах Numpy, но при работе с этими аргументами и возможными аргументами типа «утка» этот вопрос становится очень актуальным.
peterhil 12.09.2017 21:22:04

Я написал:

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

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

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

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

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

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

39
25.06.2015 03:10:35
Довольно редко у вас будет исчерпывающий список из 6 типов, которые вы хотите принять, и не будьте гибкими для других типов. Когда вам нужны такие вещи, вы, вероятно, хотите ABC. В этом случае, вероятно, это будет одна из азбуки stdlib, например collections.abc.Sizedили collections.abc.Sequence, но это может быть та, которую вы пишете сами и register(list)на которой. Если у вас действительно есть код, в котором важно отличать пустой от другого фальши, а также отличать списки и кортежи от любых других последовательностей, то это правильно, но я не верю, что у вас есть такой код.
abarnert 3.12.2014 02:09:53
Причина, по которой людям это не нравится, заключается в том, что в большинстве случаев это совершенно необычно. Python - типизированный утиной язык, и этот уровень защитного кодирования активно этому препятствует. Идея системы типов Python заключается в том, что все должно работать, пока объект передается в функции так, как ему нужно. Выполняя явные проверки типов, вы заставляете вызывающую сторону использовать определенные типы, что противоречит самой сути языка. Хотя иногда такие вещи необходимы (за исключением того, что строки рассматриваются как последовательности), такие случаи редки и почти всегда лучше, чем черные списки.
Gareth Latty 16.02.2015 20:54:10
Если вы действительно хотите проверить, что значение точно, []а не что-то ложное, другого типа, тогда, безусловно if a == []:, требуется, а не копаться в isinstance.
RemcoGerlich 16.07.2015 13:10:54
==Хотя есть некоторые автоматические принуждения . На макушке головы я не могу определить, для кого []. [] == ()например возвращается False. Но например frozenset()==set()возвращается True. Поэтому стоит хотя бы немного подумать о том, можно ли принудительно [](или наоборот) принудительно использовать какой-либо нежелательный тип a == [].
dubiousjim 16.07.2015 13:36:41
@RemcoGerlich - isinstance () по-прежнему предпочтительнее, чем создание пустого списка для сравнения. Также, как уже указывалось, оператор равенства может вызывать неявное преобразование некоторых типов, что может быть нежелательным. Нет никакой причины когда-либо кодировать «a == []», и этот код определенно будет помечен как дефект в любом обзоре кода, в котором я принимал участие. Использование соответствующего инструмента, как это предусмотрено языком, не должно рассматриваться как «гадость о "а скорее" хорошая техника программирования ".
MrWonderful 12.10.2018 04:47:51

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

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

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

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

101
23.05.2017 11:55:02

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

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

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

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

76
7.12.2017 18:50:03
Дело в том, что проверить, является ли список пустым, очень важно, по крайней мере, для меня. Задумывались ли вы, есть ли внутри какой-нибудь скрипт, <rest of code>который может использовать результат forцикла? Или напрямую использовать некоторые значения в a? Действительно, если скрипт предназначен для работы со строго контролируемым вводом, проверка может быть немного ненужной. Но в большинстве случаев входные данные различаются, и проверка обычно бывает лучше.
Amarth Gûl 2.02.2018 14:02:48
С уважением, нет. Я подумал, что кто-то, кто недостаточно разбирается в Python, знает, что «если <list>:» является правильным ответом, спрашивает, как проверить пустой список. Затем я замечаю МНОГО ответов, которые предлагают разные мнения, но, похоже, ни один из них не отвечает первоначальной потребности. Вот что я пытался сделать с моим ответом - пусть они изучат необходимость, прежде чем продолжить. Я полагаю, что я предложил так много в своем ответе, явно.
MrWonderful 17.02.2018 19:18:43
@ AmarthGûl - Как можно получить результаты цикла for для скрипта внутри <оставшегося кода> для обработки? В списке, возможно? Или, может быть, дикт? Если так, то применяется та же логика. Я не понимаю, как ввод переменных может иметь какой-либо эффект в любом разумно разработанном коде, где обработка пустого списка была бы плохой идеей.
MrWonderful 22.05.2018 22:45:27
Немного старый, но если вы просто проверяли, был ли список пустым, для непустого списка ваш код повторяет процесс снова и снова, когда OP просто ищет операцию проверки. Просто представьте себе худший сценарий для этого кода, когда n приближается к бесконечности ....
DJK 24.06.2019 22:30:32
@DJK - Нет, я думаю, что ты все еще скучаешь. Предположительно, вы хотите сделать что-то со списком, если у вас есть. Что бы вы сделали по-другому, если бы он был пустым? Вернуть рано? Что если он не пустой? обработать это? Дело, однако , в том, что вам, вероятно , не нужно проверять пустой список, просто переберите его и сделайте все, что вы собирались сделать с элементами. Если нет элементов, вы проваливаетесь. Если есть элементы, вы обрабатываете их так, как вам нужно. Дело не в том, чтобы использовать пример FOR для пустой проверки, а в том, чтобы вообще НЕ проверять, просто обработать список.
MrWonderful 27.06.2019 04:07:53

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

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

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

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

if not a:
    print('"a" is empty!')
28
11.01.2016 17:40:15
@DJ_Stuffy_K утверждают, что в модульном тестировании пустой список? Просто используйте assert(not myList). Если вы также хотите утверждать, что объект является list, вы можете использовать assertIsInstance().
Sнаđошƒаӽ 1.09.2018 05:39:51
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
11
16.12.2019 03:55:16

Вы даже можете попробовать использовать bool (), как это

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

Я люблю этот способ проверки списка пуст или нет.

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

3
13.09.2016 11:53:56
Для тех (как я), кто не знал, bool()преобразует переменную Python в логическое значение, чтобы вы могли хранить истинность или ложность значения, не используя оператор if. Я думаю, что это менее читабельно, чем просто использование условного ответа, такого как принятый ответ, но я уверен, что есть и другие хорошие варианты его использования.
Galen Long 10.03.2017 21:42:15
Это можно использовать в выражении и является более кратким.
qneill 18.12.2017 21:13:24

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

a = [] #the list

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

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

В Python пустые контейнеры, такие как списки, кортежи, наборы, запросы, переменные и т. Д., Отображаются как 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")
24
28.11.2016 14:18:03

Вдохновленный решением @ 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
5
29.03.2017 02:58:02
Чрезмерно; это просто вопрос, является ли список пустым, а не является ли что-то пустым итерируемым.
pppery 12.07.2017 15:47:09
Если бы я не был доволен if a:, это было бы потому, что я хотел исключение, если бы aне какой-то контейнер. (Быть повторяемым также позволяет использовать итераторы, которые бесполезно проверить на пустоту.)
Davis Herring 20.09.2017 02:40:33

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

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

a = []

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

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

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

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

ПКП 8

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__()метод, который возвращает ноль, когда вызывается с объектом. Вот большинство встроенных объектов, которые считаются ложными:

  • константы, определенные как ложные: 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не затенены ли они.

Затем он должен вызвать функцию, загрузить 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поле. Это используется только для объектов, которые имеют некоторое представление о длине. Этот тип не часто появляется в Python / C API. Это соответствует полям, определенным расширением 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

Ответ на комментарии:

Я хотел бы отметить, что это также верно для непустого случая, хотя он довольно уродлив, как l=[]тогда %timeit len(l) != 090,6 нс ± 8,3 нс, %timeit l != []55,6 нс ± 3,09, %timeit not not l38,5 нс ± 0,372. Но никто не получит удовольствия, not not lнесмотря на тройную скорость. Это выглядит смешно. Но скорость выигрывает,
я полагаю, что проблема заключается в тестировании со временем, так как просто if l:достаточно, но неожиданно %timeit bool(l)дает 101 нс ± 2,64 нс. Интересно, что без этого наказания невозможно навязать бул. %timeit lбесполезен, так как никакого преобразования не произойдет.

Волшебство IPython %timeit, здесь не совсем бесполезно:

In [1]: l = []                                                                  

In [2]: %timeit l                                                               
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [3]: %timeit not l                                                           
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not l                                                       
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

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

In [5]: %timeit if l: pass                                                      
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [6]: %timeit if not l: pass                                                  
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit if not not l: pass                                              
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Теперь давайте посмотрим на случай списка безработных:

In [8]: l = [1]                                                                 

In [9]: %timeit if l: pass                                                      
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [10]: %timeit if not l: pass                                                 
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit if not not l: pass                                             
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Здесь мы видим, что не имеет большого значения, передаете ли вы фактическую boolпроверку состояния или сам список, и, если что-то, предоставление списка, как есть, происходит быстрее.

Python написан на C; он использует свою логику на уровне C. Все, что вы пишете на Python, будет медленнее. И это, вероятно, будет на несколько порядков медленнее, если вы не используете механизмы, встроенные непосредственно в Python.

213
28.11.2019 14:45:42
Я хотел бы отметить, что это также верно для непустого случая, хотя он довольно уродлив, как l=[]тогда %timeit len(l) != 090,6 нс ± 8,3 нс, %timeit l != []55,6 нс ± 3,09, %timeit not not l38,5 нс ± 0,372. Но никто не получит удовольствия, not not lнесмотря на тройную скорость. Это выглядит смешно. Но скорость выигрывает
Gregory Morse 28.11.2019 05:52:15
Я полагаю, что проблема заключается в тестировании со временем, поскольку if l:достаточно, но неожиданно %timeit bool(l)получается 101 нс ± 2,64 нс. Интересно, что без этого наказания невозможно навязать бул. %timeit lбесполезен, так как никакого преобразования не произойдет.
Gregory Morse 28.11.2019 06:31:53

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

2
20.09.2017 02:59:54
Название is_emptyпредполагает, что оно что-то возвращает. Но если это произойдет, то это будет что-то bool(any_structure), что вы должны использовать вместо этого ( когда вам boolвообще нужно ).
Davis Herring 20.09.2017 02:39:05
Почему мы хотим, чтобы вариант bool(также) печатал сообщения на стандартный вывод?
Davis Herring 20.09.2017 03:13:03
@DavisHerring У нас всегда есть два варианта: сначала напечатать, используя функцию, а другой - использовать возвращаемую boolпеременную. Твой выбор. Я пишу оба, чтобы вы могли выбирать между ними.
Vineet Jain 20.09.2017 03:45:30

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

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

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

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.
5
12.02.2020 10:57:34
все (bool (x) для x в l) истинно для пустого списка
gberger 5.03.2018 17:27:17

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

1
6.06.2018 19:19:25

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

if len(a) == 0:
    print("a is empty")
3
12.10.2018 02:59:58

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

not a

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

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
8
12.10.2018 04:01:59
Возможно, это вызывает исключение, если aне является списком и aне имеет __len__реализованного метода . Я бы порекомендовал:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger 10.01.2019 09:40:10
@ Свенкрюгер Нету. Оператор andленив в Python. Ничто после andне будет выполнено, если условие перед andложно.
ElmoVanKielmo 26.02.2019 14:00:29
print('not empty' if a else 'empty')

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

a.pop() if a else None

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

if a: a.pop() 
4
4.10.2019 23:24:32

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

a == []

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

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

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

4
6.11.2018 10:12:22
пожалуйста, дайте больше объяснений о том, как это работает без написания "если"?
ganeshdeshmukh 30.12.2018 10:48:00
Это не питон, ни полный пример. Кроме того, он создает пустой список каждый раз, когда встречается. Не делай этого.
MrWonderful 29.04.2019 08:53:32
@MrWonderful не создает пустой экземпляр каждый раз. Он просто проверяет, является ли существующий список aпустым или нет.
Tessaracter 6.04.2020 15:44:54
@MrWonderful Я не понимаю, что делает этоpythonic
Tessaracter 6.04.2020 15:45:29
@ganeshdeshmukh, если вы используете a==[]его, напечатает true на терминале python, если a пусто. Иначе это напечатает Ложь. Вы можете использовать это внутри условия if также какif(a==[])
Tessaracter 6.04.2020 15:47:07

Чтобы проверить, является ли список пустым или нет, вы можете использовать два следующих способа. Но помните, нам следует избегать способа явной проверки типа последовательности (это 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 True
    else: 
        return False

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

list1 = [] 

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

# Result: "The list is Empty"

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

0
12.02.2020 11:38:32

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

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
6
27.07.2019 18:44:40
-1 - Чтобы избежать путаницы, не используйте зарезервированные слова для имен переменных, иначе вы можете столкнуться с неожиданным поведением при следующем вызове, например, list () »... что-то вроде« TypeError: объект list » не вызывается "или что-то подобное.
MrWonderful 29.04.2019 09:08:52

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

if not a : 
   print ("Empty") 

Способ 2:

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

Способ 3:

if a == [] :
  print ("Empty")
19
9.02.2019 23:59:54

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

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это лучший выбор.

1
27.07.2019 18:43:04