Imagine, you iterate through a collection, which contains some other collections.
Like so: list of lists
In [32]: L = [ [i] for i in range(10) ]
In [33]: L
Out[33]: [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
One obvious way to iterate over inner values is to use indexing:
In [24]: [ i[0] for i in L ]
Out[24]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Well, there is another way to do so. Almost so :)
In [24]: [ i for i, in L ]
Out[24]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In fact, it is single element unpacking. It works, because in python commas "construct" tuples, not brackets
In [29]: 5,
Out[29]: (5,)
In [30]: (5)
Out[30]: 5
Are there any differences?
Yeap.
This unpacking seems to be faster than reading by index. Not much, by ~10%.
In [24]: L = [ [i] for i in range(1000) ]
In [25]: %timeit [ i for i, in L ]
19.7 µs ± 31.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [26]: %timeit [ i[0] for i in L ]
22.1 µs ± 150 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
Also, there is logical difference.
If we take a list of empty lists as input, both statements will fall with different exceptions:
In [30]: [ i[0] for i in L+[[]] ]
# IndexError: list index out of range
In [31]: [ i for i, in L+[[]] ]
# ValueError: not enough values to unpack (expected 1, got 0)
However, if we have more than 1 element in any of inner lists, then:
- unpacking will fall with
ValueError: too many values to unpack (expected 1)
- and reading by index will silently return first elements of lists
"Explicit is better than implicit" - they say, huh?
Hope you enjoyed! :)
Top comments (0)