A tuple is an invariable sequence, so when it is created (and its memory allocated), it needs to know how many elements it will contain in the first place. This means that when creating a tuple from a generator expression, the generator must first be iterated, but because the generators can be consumed only once, and the elements need to be stored somewhere. So what happens can be compared with this:
tuple(list(generator))
Now creating a list from a generator expression is slower than creating a list using list comprehension, so you can save time just by creating a list using list comprehension.
And if you have no real reason to use a tuple, i.e. if you do not require immutability, you can also save the list and not convert it to a tuple to save a little more time.
Finally, no, in fact there is no better way to iterate over indexes and query the sequence for each. Even if the indices are the same all the time, they still need to be evaluated for each list, so you still have to repeat it.
However, you can save some more time if these indexes are actually fixed. Since simple (l[1], l[5], l[9]) will be much faster than anything else;)
Here are some links from the source (3.4 is used here, but it should look like 2.x):
Creating a tuple using the built-in tuple() function is done in the PySequence_Tuple function.
If the argument is a list, then Python will handle this explicitly by calling PyList_AsTuple , which essentially selects a tuple of list length and then simply copies all the elements.
Otherwise, it will create an iterator from the argument and first try to guess the length. Since generators have no length, Python will use the default assumption of 10 and highlight the tuple of this note length, which for your tuple, we have allocated 7 spaces too much. He then iterates over the iterator and assigns each value to its place in the tuple. Subsequently, it will resize the created tuple .
Now the real difference most likely works in list display methods. List enumeration is essentially a sequence of low-level add-on lists. Thus, this works in the same way that tuples are populated in PySequence_Tuple , described above. Thus, both methods will be equal. However, the difference with the generator expressions is that they have overhead that actually creates the generator (output sequence) that needs to be sorted out. Thus, all this is superfluous, which you avoid when you have an understanding of the list.