3

I've been using python3 a lot for a class recently and figured out that you can write

if x in [1,2,3]:
    print("x is 1,2 or 3")

instead of

if x == 1 or x == 2 or x ==3:
    print("x is 1,2 or 3")

Is this considered good or bad practice, is it "pythonic" ?

Edit

The consensus seems to be that

if x in {1,2,3}: # set {}, not list []
    print("x is 1,2 or 3")

is more efficient, O(1) vs O(n), and therefore faster. Also, it expresses the same things less verbosely which makes it more "pythonic" as well.

Philip Nelson
  • 1,027
  • 12
  • 28

3 Answers3

7

TL;DR:

Yes.

Longer Answer:

It isn't less efficient for sure, as @Selcuk mentioned in the comments:

The performance difference comes from implementation overheads, otherwise they are both O(n) while set operation is actually faster as it is O(1).

Hearing set should confuse you, first read through everything and at the end you will see set membership testing, here are the timings:

from timeit import timeit
x = 2
print(timeit(lambda: x in [1, 2, 3], number=10000000))
print(timeit(lambda: x == 1 or x == 2 or x == 3, number=10000000))

Output:

2.9532112044043597
3.614175814476062

So it means, that your first solution with list membership testing is faster than multiple or conditions.

As @Austin mentioned, set membership testing is faster.

So if we check set membership timing, like:

from timeit import timeit
x = 2
print(timeit(lambda: x in {1, 2, 3}, number=10000000))

It will output:

2.7767165870317445

So set membership is the fastest.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
2

A slight version of first one would be more pythonic:

if x in {1,2,3}:

Always a membership check on set is of constant time, though there would be a set creation time (which in some cases can be a bottleneck).

Austin
  • 25,759
  • 4
  • 25
  • 48
1

The in keyword has two purposes:

  • The in keyword is used to check if a value is present in a sequence (list, range, string etc.).

  • The in keyword is also used to iterate through a sequence in a for
    loop

As to my knowledge the "in" calls the eq method to check if the given entry matches the current list in this case hence forth both achieve the same thing. As to answer the question if this is "pythonic", then yes the in function saves several lines of iteration that were previously required to iterate and compare the list or any other data structure.

Here is the time complexity documentation for future reference , it also explains the time complexity of the in keyword which is O(n) on average