To understand what happened in your code, a tip would be to do the table test. But basically, the problem is that you made a loop within another. That is, for each index k
, you make another loop by the lists a
and b
, updating the indexes and overwriting the value going in the position k
.
For example, in the first iteration, when k
is equal to zero:
- you make a
for
for a
and b
:
- as
k
is even, it receives the first element of a
- in the next iteration, the index
k
receives the second element of a
- in the next iteration, the index
k
receives the third element of a
- and so on, down to the last element of
a
In the next iteration of for
external, k
is equal to 1, and therefore odd. Thus, the index k
will receive the first element of b
, then the second, etc., until receiving the last.
At the end, all even positions of c
shall have the last element of a
and all odd positions shall have the last element of b
.
In Python, lists are dynamic and you can add elements as needed. No need to create a list c
with 20 elements only to have the indexes. You only need to go through a
and b
and add the elements in c
:
c = []
for n1, n2 in zip(a, b):
c.append(n1)
c.append(n2)
That’s it. The list c
starts empty, and with each iteration I add an element of a
and another of b
- the first element inserted will be at index zero and the second at index 1. Then, in the next iteration, the third element will be at index 2 and the fourth at index 3, and so on. I don’t even have to keep testing the ratings.
Remember that when iterating with zip
, the loop only goes until the smallest of the lists ends. But as in this case both have the same size, there is no such concern.
Another alternative is to take the tuple returned by zip
and insert both at once:
c = []
for values in zip(a, b):
c.extend(values)
Another way to do it is to use the module itertools
, along with a comprehensilist on:
from itertools import chain
c = list(chain.from_iterable(zip(a, b)))
If I just did c = list(zip(a, b))
, a list of tuples would be created, but using chain.from_iterable
i guarantee that each element of each tuple will be an element of the list.
If you want even create the list c
with the final size and use the indexes (although the above alternatives are more pythonic), a solution would be:
# cria a lista com o tamanho de a + tamanho de b
c = [ '' ] * (len(a) + len(b))
for i in range(len(c)):
# os índices de a e b correspondem à metade do respectivo índice de c
if i % 2 == 0:
c[i] = a[i // 2]
else:
c[i] = b[(i - 1) // 2]
But as I said, I think it’s unnecessary to create a list with several values that will be discarded next, just to have it with the right size and be able to iterate through the indexes. The above solutions that insert the elements as they are traversed seem to me much simpler.
Why do
for n1, n2 in zip(a, b)
?– Woss
I saw that you canceled my answer below. Something was missing from it?
– hkotsubo