tuple vs list

One small thing in Python3 that continues to confound me is how dict.values, dict.keys, and zip all don’t return real collections but instead iterables. That means you have to wrap them first in a tuple or list if you want to array index the output. It’s not a huge deal, but it’s a nuisance.

So which is better? Tuple or list? Tuple should be in theory, because it’s immutable it should be a little more efficient. Seems to be that way in practice too.

$ python3 -m timeit 'tuple({"a":1}.values())[0]'
1000000 loops, best of 3: 0.266 usec per loop
$ python3 -m timeit 'list({"a":1}.values())[0]'
1000000 loops, best of 3: 0.331 usec per loop

$ python2 -m timeit 'tuple({"a":1}.values())[0]'
1000000 loops, best of 3: 0.227 usec per loop
$ python2 -m timeit 'list({"a":1}.values())[0]'
1000000 loops, best of 3: 0.256 usec per loop

(You know, every time I do a timeit on python2 vs python3, python3 is measurably slower. Some of that is due to Unicode but I don’t think that’s all of it.)

2 thoughts on “tuple vs list

  1. In case you haven’t run across it – there’s an itertools ‘recipe’ which is more efficient for larger iterables (no alloc, only as much traversal as needed). It’s in the docs at https://docs.python.org/3.5/library/itertools.html#itertools-recipes

    For your benchmark, next(iter(values)) is faster than the tuple although perhaps even more inscrutable at first glance. Or not, if you’re into Python’s funky ‘objects have protocols that are exposed through global built-ins’ thing.

  2. Thanks! I’d tried next(values) and was confused why it didn’t work. I forgot that values is an iterable, not an iterator itself. Oy. The “no alloc” thing is a very important optimization if the size of the iterable is at all large. My toy example with 1 item, not so much, but for real data…

Comments are closed.