1

A very common pattern in python is:

for something in ['an', 'iterable']:
    func(something)

I almost always see the iterable as a list (like in this example), but it could very well be a tuple, set, or something else. Is the list the most performant and pythonic way to do this?

Similarly, I often see the following:

if something_else in ['another', 'iterable']:
    func(something_else)

In this case, we're actually searching for something_else (note the if instead of for) which would probably be more performant if the iterable was a set (e.g. if x in {...}:). However, this might not necessarily be true for very small quantities. Is a list still the pythonic way to do this?

s g
  • 5,289
  • 10
  • 49
  • 82
  • I think tuple is a little bit faster since its data structure is simpler... However I think both way (the list and the tuple) are pretty and equally pythonic. Therefore I don't deliberately distinguish them. – Philip Tzou May 01 '19 at 00:31
  • For the first case, I agree with @sg - For anything but a gigantic list, it isn't going to matter which is technically the most performant thing, and I think either a list or a tuple would be the most performant anyway. I think the choice should come down to readability, and it's hard for anything to be more readable than your sample code. - For the second case, a set is going to start to be significantly more efficient as the list of items gets large. (this assumes you'd do a lookup in that list multiple times) – CryptoFool May 01 '19 at 00:36
  • 1
    https://stackoverflow.com/questions/68630/are-tuples-more-efficient-than-lists-in-python – Jackson H May 01 '19 at 00:45

3 Answers3

1

Forget about arguments regarding timing, they are irrelevant to what you are doing and they might vary across different Python implementations. It's better to optimize for readability instead

To answer your question, I believe that the list is the most "Pythonic" one. Most Python developers use lists for just about anything and nobody will look at your code and think it's weird. The list square brackets ([ ]) is also very distinct and easy to identify while scanning through the code. The set brackets ({ }) can be confused with a dict and beginners might not be familiar with the notation. The tuple parenthesis is a weird one: parenthesis are used everywhere is Python and the syntax can be confusing. e.g: a tuple of a single item requires a comma: ('item',)

Having said that, being "Pythonic" is like following a fashion: what's fashionable today might not be fashionable in a few years since the language changes, people change, library changes, etc. I am a big fan of using the "proper" types as much as possible. Are you dealing with a set (in a mathematical sense) or a list? if it's a set, use a set otherwise list.

Cesar Canassa
  • 18,659
  • 11
  • 66
  • 69
0

I guess timeit is a thing. Here are the results:

$ python -m timeit "x=True if 'my_variable' in ['just', 'three', 'options'] else False"
10000000 loops, best of 3: 0.0643 usec per loop
$ python -m timeit "x=True if 'my_variable' in ('just', 'three', 'options') else False"
10000000 loops, best of 3: 0.0645 usec per loop
$ python -m timeit "x=True if 'my_variable' in {'just', 'three', 'options'} else False"
10000000 loops, best of 3: 0.113 usec per loop

Longer set of options:

$ python -m timeit "x=True if 'my_variable' in ['a', 'much', 'longer', 'list', 'of', 'choices', 'but', 'still', 'nothing', 'crazy', 'and', 'perhaps', 'you', 'could', 'actually', 'find', 'some', 'ridiculous', 'code', 'like', 'this', 'in', 'the', 'wild'] else False"
1000000 loops, best of 3: 0.264 usec per loop
$ python -m timeit "x=True if 'my_variable' in ('a', 'much', 'longer', 'list', 'of', 'choices', 'but', 'still', 'nothing', 'crazy', 'and', 'perhaps', 'you', 'could', 'actually', 'find', 'some', 'ridiculous', 'code', 'like', 'this', 'in', 'the', 'wild') else False"
1000000 loops, best of 3: 0.262 usec per loop
$ python -m timeit "x=True if 'my_variable' in {'a', 'much', 'longer', 'list', 'of', 'choices', 'but', 'still', 'nothing', 'crazy', 'and', 'perhaps', 'you', 'could', 'actually', 'find', 'some', 'ridiculous', 'code', 'like', 'this', 'in', 'the', 'wild'} else False"
1000000 loops, best of 3: 0.82 usec per loop

Tuples and Lists perform the same, and they are clearly faster than sets. I would imagine this is because the sets come with a lot more overhead and thus aren't as practical when N is small. For lots more performance related information comparing tuples and lists, see the various answers on Are tuples more efficient than lists in Python?

As for style, I don't think there is really any difference.

s g
  • 5,289
  • 10
  • 49
  • 82
0

Given that there isn't a significant difference, as s g indicates, lists are probably preferable. List usage is somewhat more common, and therefor more conventional, and square brackets are arguably more recognizable as a collection than round brackets, which are used for many more things.

Toren Darby
  • 61
  • 2
  • 4