This form is called list comprehension, or in English list comprehensions. It is nothing more than a simplified way of writing a loop for
. In this case I even used it inappropriately, because the final code was not as readable as it should be in a Python code, but the code equivalent to this would be:
groups = []
for i in range(0, len(text), key):
value = text[i:i+key] # Pega o trecho da string de i até i+key
value = value.ljust(key, "*") # Garante que a string possua "key" caracteres, adicionando *
groups.append(value) # Adiciona o valor final à lista
This above code, for practical purposes, does exactly the same thing as the line presented in the question:
groups = [text[i:i+key].ljust(key, "*") for i in range(0, len(text), key)]
This syntax is defined to make the code more concise and much more readable - at least this is the goal (not always used correctly hehe). In unofficial sources, one can read that the understanding of lists is even faster than a for
normal mainly due to internal language implementations. I’ve never particularly tried to prove this in practice and I don’t remember seeing any official source to prove it, but at the very least, it has the same performance, so you can use it fearlessly.
Even, one can use the understanding of nested form lists, for example, to traverse a "matrix", which requires a for
for rows and one for columns.
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
double_matrix = [[2*matrix[i][j] for j in range(3)] for i in range(3)]
The result would be the "matrix" multiplied by 2:
[
[ 2, 4, 6],
[ 8, 10, 12],
[14, 16, 18]
]
For the equivalent code would be:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
double_matrix = []
for i in range(3):
row = []
for j in range(3):
row.append(2*matrix[i][j])
double_matrix.append(row)
References
Official documentation: List Comprehensions
This syntax is also valid for defining dictionaries. Suppose we want to create a dictionary with integer keys from 0 to 4, whose dictionary value refers to twice the key. With a loop for
, we could do:
d = {}
for i in range(5):
d[i] = 2*i
print(d)
See working on Ideone.
The syntax using Dict comprehensions would be:
d = {i: 2*i for i in range(5)}
See working on Ideone.
The main difference is that while understanding lists is defined between brackets, []
, which is the syntax of lists, the understanding of dictionaries is defined between keys, {}
, which is the syntax of dictionaries, besides defining the key/value pair and i: 2*i
.
That said, it is possible to think that it would also be possible to define a tuple with this syntax only using parentheses, ()
, which is the tuple syntax. Wrong. The tuple is an immutable type of Python and therefore could not be changed next to the loop for
, but that doesn’t mean that the syntax using parentheses is wrong.
In fact, when using parentheses, what is defined is a generator. That is, do something like:
g = (2*i for i in range(5))
See working on Ideone.
It would be the same as:
def temp():
for i in range(5):
yield 2*i
g = temp()
In these cases, you could iterate on the generator or simply convert it to a list:
l = list(g)
print(l)
See working on Ideone.
In some cases it would be possible to omit the parentheses, so when you see the syntax without the parentheses, know that it is also a definition of a generator. To quote an example, the calculation of the sum of the values between 0 and 5:
s = sum(i for i in range(5))
See working on Ideone.
Take a look at this Link.
– Solkarped