Search code examples
pythonpython-3.xlistunpackiterable-unpacking

Pythonic way to unpack an iterator inside of a list


I'm trying to figure out what is the pythonic way to unpack an iterator inside of a list.

For example:

my_iterator = zip([1, 2, 3, 4], [1, 2, 3, 4])

I have come with the following ways to unpack my iterator inside of a list:

1)

my_list = [*my_iterator]

2)

my_list = [e for e in my_iterator]

3)

my_list = list(my_iterator)

No 1) is my favorite way to do it since is less code, but I'm wondering if this is also the pythonic way. Or maybe there is another way to achieve this besides those 3 which is the pythonic way?


Solution

  • After exploring more the subject I've come with some conclusions.

    There should be one-- and preferably only one --obvious way to do it

    (zen of python)

    Deciding which option is the "pythonic" one should take into consideration some criteria :

    • how explicit,
    • simple,
    • and readable it is.

    And the obvious "pythonic" option winning in all criteria is option number 3):

    list = list(my_iterator)

    Here is why is "obvious" that no 3) is the pythonic one:

    • Option 3) is close to natural language making you to 'instantly' think what is the output.
    • Option 2) (using list comprehension) if you see for the first time that line of code will take you to read a little bit more and to pay a bit more attention. For example, I use list comprehension when I want to add some extra steps(calling a function with the iterated elements or having some checking using if statement), so when I see a list comprehension I check for any possible function call inside or for any if statment.
    • option 1) (unpacking using *) asterisk operator can be a bit confusing if you don't use it regularly, there are 4 cases for using the asterisk in Python:

      1. For multiplication and power operations.
      2. For repeatedly extending the list-type containers.
      3. For using the variadic arguments. (so-called “packing”)
      4. For unpacking the containers.

    Another good argument is python docs themselves, I have done some statistics to check which options are chosen by the docs, for this I've chose 4 buil-in iterators and everything from the module itertools (that are used like: itertools.) to see how they are unpacked in a list:

    • map
    • range
    • filter
    • enumerate
    • itertools.

    After exploring the docs I found: 0 iterators unpacked in a list using option 1) and 2) and 35 using option 3).

    enter image description here

    Conclusion :

    The pythonic way to unpack an iterator inside of a list is: my_list = list(my_iterator)