Build Python lists from another iterable, and show the list comprehension and generator expression forms.
There are several ways to turn an iterable into a list, and they differ in what they produce.
source = "abc"
print(list(source)) # ['a', 'b', 'c']
print([c for c in source]) # ['a', 'b', 'c'] - the comprehension
print(list(range(3))) # [0, 1, 2]
print(sorted({3, 1, 2})) # [1, 2, 3] - sorted always returns a list
# A generator expression gives an iterator, not a list
lazy = (c for c in source)
print(type(lazy).__name__) # generator
print(list(lazy)) # ['a', 'b', 'c']
# Repetition builds a list of references
zeros = [0] * 5
print(zeros) # [0, 0, 0, 0, 0]list(iterable) is the general conversion and works with any iterable, including generators and file objects. A list comprehension does the same job while letting you transform or filter each item on the way, and it is usually faster because the loop runs without the repeated method lookups that a Python-level for loop performs.
The generator expression in parentheses looks almost identical to a comprehension in square brackets, but the difference is what you get back. The comprehension evaluates immediately and produces a list. The generator expression produces a generator object that computes each item on demand, so nothing is stored and nothing is computed until you iterate.
The repetition form needs a warning. The list [0] * 5 is fine because integers are immutable and each slot holds a reference to the same zero. But [[]] * 3 creates three references to the same inner list, so appending to one of them changes all three. To build three independent lists you need a comprehension: [[] for _ in range(3)].