16

My colleague uses this way in conditions

if len(A) is not 0:
    print('A is not empty')

I prefer this one

if A:
    print('A is not empty')

What is prop-cons arguments?

Her point is that first way is more straight-forward way to show what she exactly wants. My point is that my way is shorter.

Also first way is 2 times faster then my one:

>>> import timeit
>>> timeit.timeit('len(A) is not 0', setup='A=[1,2,3]')
0.048459101999924314
>>> timeit.timeit('bool(A)', setup='A=[1,2,3]')
0.09833707799998592

But

>>> import timeit
>>> timeit.timeit('if len(A) is not 0:\n  pass', setup='A=[1,2,3]')
0.06600062699999398
>>> timeit.timeit('if A:\n  pass', setup='A=[1,2,3]')
0.011816206999810674 

second way 6 times faster! I am confused how if works :-)

vladimirfol
  • 435
  • 1
  • 5
  • 9
  • 10
    `if len(A) is not 0:` is dangerous because it is not guaranteed that the references are identical (`is` and `is not` do reference checks). `if A` tests the truthiness (emptiness) and is safe. – cs95 Jan 09 '19 at 10:09
  • 1
    please have a look at this post.. [if A vs if A is not None:](https://stackoverflow.com/questions/7816363/if-a-vs-if-a-is-not-none) – Karthikeyan K Jan 09 '19 at 10:10
  • Personally I find your way more intuitive and straight-forward. – cdarke Jan 09 '19 at 10:11
  • I thought that for integers "is" check is guaranteed to be "==" check. Can you show me an example when they do not match? – vladimirfol Jan 09 '19 at 10:11
  • 2
    Shouldn't be using `is not 0` in any case. It should be `!=0`. – khelwood Jan 09 '19 at 10:12
  • 3
    @vladimirfol: that's implementation specific. Can you show me a statement in the python doc. where it says the are guaranteed to be the same? – cdarke Jan 09 '19 at 10:12
  • 2
    @vladimirfol `x = 257; x is 257` fails. CPython interns only small integers. – L3viathan Jan 09 '19 at 10:15
  • 2
    @L3viathan: In Idle (3.6.6) this is `True`. It fails for me if I write the statements in different lines. – Matthias Jan 09 '19 at 10:16
  • 1
    @Matthias In other words, it cannot be relied upon. – deceze Jan 09 '19 at 10:17

4 Answers4

21

PEP 8 style guide is clear about it:

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Mikhail Gerasimov
  • 36,989
  • 16
  • 116
  • 159
  • 2
    But be careful with Numpy arrays: while `bool([0])` and `bool([False])` evaluate to `True`, `bool(numpy.array([0]))` and `bool(numpy.array([False]))` evaluate to `False`, so you should use `len` explicitly in this particular case. – Géry Ogam Feb 27 '19 at 17:32
  • 1
    I agree and disagree at the same time, PEP its a convention and we should be aware of it, but not a rule. There is another perspective, which I like to follow nowadays: https://stackoverflow.com/a/64070199/6485445 – mseromenho Mar 02 '22 at 19:34
3

I would argue that if A = 42, your colleague code would raise an error

object of type 'int' has no len()

while your code would just execute whatever comes after the if.

Statistic Dean
  • 4,861
  • 7
  • 22
  • 46
  • 2
    Arguably if the code is *expecting* a list, that’s something of a nonissue. – deceze Jan 09 '19 at 10:16
  • That's true, but if you use this all the time, i'll guarantee you, there will be a time where you get something else than a list as the input of this, and you might lose quite some time debugging. – Statistic Dean Jan 09 '19 at 10:47
  • 2
    Well, on the contrary, this would raise a visible exception due to an unexpected type, rather than silently swallowing the problem. – deceze Jan 09 '19 at 10:49
  • @StatisticDean i'm not sure if you're saying that's a good thing or a bad thing - it seems to me that in general you want your code to error when your input is not what you expected - which is a point in favour of the 'colleague code' (although the OPs code is the correct python implementation, as the other answers have said) – Stael Jan 09 '19 at 11:01
  • @Stael I'm not taking a stance on whether it's good or bad, just pointing out the difference. In general, I would agree with you on having an error is better than having your code execute in the wrong way. – Statistic Dean Jan 09 '19 at 12:53
2

1.

if len(A) is not 0:
    print('A is not empty')

2.

if A:
    print('A is not empty')

the difference between first way and second way is that you can use len(A) only for structure like list,tuples,dictionary as they support the len() fuction but you can not use the len() fuction for data or like characters, strings, integers(numbers).

for example:

len(123), len(abc), len(123abc) : will raise an error.

but, list = [1,2,3,4,5]

len(list) will not raise an error

if A:
    statement  # this is useful while our only concern is that the variable A has some value or not 
Abhishek-Saini
  • 733
  • 7
  • 11
1

You are not comparing the same thing. If you compare this:

import timeit
print(timeit.timeit('if len(A) is not 0:\n  pass', setup='A=[1,2,3]'))
print(timeit.timeit('if A:\n  pass', setup='A=[1,2,3]'))

You will see that your method is faster. Plus your method is a more pythonic way.

T.Lucas
  • 848
  • 4
  • 8