The problem is that all the sublists that your list contains tabla
are actually the same list, they have the same reference. When you modify a value in one the rest are also modified since they are actually the same object. When your cycle finishes you assign the value "T" to the first element of the last "line", as in fact all the lines are the same list is reflected in all.
Simply add a copy of your línea
list each time you add one to the matrix:
tabla.append(linea[:])
Slicing or slicing is used to return a shallow copy
so that now each sublist of tabla
is a different object, a different list. It is equivalent to:
import copy
tabla.append(copy.copy(linea))
One thing must be taken into account. The fila
list is copied but its content is not copied, the same references are used. In your case they only seem to get immutable objects (strings) so if you modify a string it will not be reflected in the other lists. This is because "modifying" an immutable object involves creating a new object.
This does not happen if they were mutable objects, in this case you should use a deep copy , so that both the list and all the objects it contains are copied recursively:
import copy
tabla.append(copy.deepcopy(linea))
An alternative to doing what you do using compression lists would be:
tabla = [[elem] + ["" for _ in range(3)]
for elem in ['1', '2', '3', '4', '5', '6', 'E', 'F', 'P', 'G', '2G', 'T']]
Edit:
In case you are interested you can see the behavior described above in detail with an example:
>>> lista1 = [1, "a", (1, 2), ["c"]]
>>> lista2 = lista1
This does not copy lista1
, it simply assigns the same reference to variable lista2
. Both identifiers point to the same list, to the same object in memory. We can see it using id
:
>>> id(lista1)
140001243246088
>>> id(lista2)
140001243246088
Modifying one implies modifying the other (both are the same in reality):
>>> lista1[0] = 147
>>> lista1
[147, 'a', (1, 2), ['c']]
>>> lista2
[147, 'a', (1, 2), ['c']]
Now let's see what a shallow copy is:
>>> lista2 = lista1[:] # equivalente a lista2 = copy.copy(lista1)
In this case lista1
and lista2
are two different objects:
>>> id(lista1)
140001243246088
>>> id(lista2)
140001243245192
But not the elements they contain:
>>> id(lista1[0])
140001273510848
>>> id(lista2[0])
140001273510848
If we modify an immutable element, the change is only reflected in the list that is applied, since it implies the creation of a new object. If we modify a mutable object as a list, the change is reflected in both lists:
>>> lista1[0] += 777
>>> lista1[3].append("Hola")
>>> lista1
[924, 'a', (1, 2), ['c', 'Hola']]
>>> lista2
[147, 'a', (1, 2), ['c', 'Hola']]
For the mutable objects to be different objects we need a deep copy:
>>> import copy
>>> lista2 = copy.deepcopy(lista1)
>>> lista1
[777, 'a', (1, 2), ['c', 'Hola']]
>>> lista2
[777, 'a', (1, 2), ['c', 'Hola']]
>>> lista1[3].append("Mundo")
>>> lista1
[777, 'a', (1, 2), ['c', 'Hola', 'Mundo']]
>>> lista2
[777, 'a', (1, 2), ['c', 'Hola']]