103

Is try-catch the only method to do that?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Ilya Smagin
  • 5,992
  • 11
  • 40
  • 57
  • 5
    Most certainly this question would be downvoted and closed immediately if posted today. Interestingly, 10 years ago, people thought otherwise. – Abhijit Sarkar Sep 27 '21 at 18:30

3 Answers3

175

If d is your deque, use

if d:
    # not empty
else:
    # empty

This will implicitly convert d to a bool, which yields True if the deque contains any items and False if it is empty.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 3
    other techniques include `d_empty = False if d else True` – theheadofabroom Apr 13 '11 at 16:28
  • 1
    You can also write `if len(d) == 0` if the implicit conversion is too cute for you (and in fact, that's what the conversion to bool is doing under the hood). – dfan Apr 13 '11 at 16:28
  • 28
    `if d` is the cannonical way for all collections (tuples, strings, lists, dicts and all their many subtypes). – Jochen Ritzel Apr 13 '11 at 16:43
  • 8
    @dfan: This is explicitly discouraged by [PEP 8](http://www.python.org/dev/peps/pep-0008/). – Sven Marnach Apr 13 '11 at 16:53
  • @Sven Marnach: Thanks. I was looking at [this discussion](http://bugs.python.org/issue3891) where Raymond Hettinger says `There are standard ways to test for an empty container "if c:" or "if len(c)" or "if len(c) > 0". This is Python 101.` But that was written two and a half years ago and in any case has less force than an official style guide from Guido :) – dfan Apr 13 '11 at 17:09
  • Why is this the most efficient way to check? – aerin Jan 29 '19 at 23:42
  • 1
    Note that in Python len() is O(1) (i.e. it doesn't iterate over all the elements and count them), in which case I think @dfan's way is the most readable and is also just as efficient. – ritmatter Feb 25 '19 at 01:19
  • 2
    @ritmatter As I stated before, the official Python style guide explicitly discourages `if len(d) == 0`, and I personally prefer the more succinct `if d` as well. I think there is a benefit to sticking with the official style guide, since it makes Python code more consistent across code bases. – Sven Marnach Feb 25 '19 at 09:51
  • Speaking as the person who suggested `if len(d) == 0`, I agree with Sven. – dfan Feb 25 '19 at 12:08
  • How did you discover this `if d:` behaviour? I had the same question as OP, but I first went over the [docs](https://docs.python.org/3/library/collections.html#collections.deque). There's no way I would have guessed this approach from what i read about deque objects... I'm starting to wonder if there's a more informative set of docs than python.org that I should be checking, or perhaps I'm just missing important info when I'm reading? – RTbecard Jan 13 '20 at 15:32
  • 4
    @RTbecard: This is common to _all_ collections in Python, and is considered a rather fundamental Python idiom. The documentation indeed doesn't point it out explcitly for every single data type. Any type that supports `len()` [also supports conversion to a `bool`](https://docs.python.org/3/reference/datamodel.html#object.__bool__). – Sven Marnach Jan 14 '20 at 08:26
  • 1
    It is important to note that this technique of conversion to boolean does not work for all kinds of containers. Take for example `queue.Queue` from an external library `queue`. The conversion of `Queue` instance to `bool` always returns `True`. Applying the PEP8 technique without this knowledge results in a code that is quite difficult to debug afterwards, and `Queue.empty()` should be used instead. Note that the interface of `queue.Queue` is different from that of `collections.deque`. – Sergey Dovgal Aug 04 '22 at 12:50
15

There are two main ways:

  1. Containers can be used as booleans (with False indicating the container is empty):

  2. Containers in Python also have a __len__() method to indicate their size.

Here are a few patterns:

non_empty = bool(d)     # Coerce to a boolean value

empty = not d           # Invert the boolean value

if d:                   # Test the boolean value
    print('non-empty')

while d:                # Loop until empty
    x = d.pop()
    process(x)

if len(d) == 0:         # Test the size directly
   print('empty')

The latter technique isn't as fast or succinct as the others, but it does have the virtue of being explicit for readers who may not know about the boolean value of containers.

Other ways are possible. For example, indexing with d[0] raises an IndexError for an empty sequence. I've seen this used a few times.

martineau
  • 119,623
  • 25
  • 170
  • 301
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
1
from collections import deque

d = deque()

print(True) if len(d) == 0  else print(false)
Hemanta
  • 11
  • 2