What you are trying to do is an interleave of two sequences. The reason you are seeing the error is because ascii_username
and ascii_password
are not the same length. When you are trying to assign to the slice of the list, you have to supply the exact number of elements in the slice.
It is easy to see in this example: slicing x
at step size of 2 has more elements than y
.
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = 'yes'
z = 'nope!'
print(x[::2])
# prints:
[1, 3, 5, 7]
print(list(y))
['y', 'e', 's']
Trying to assign to x[::2]
leaves a dangling 7
that is not reassigned.
To fix this problem, you can use interleave_longest
from the more_itertools
package.
from more_itertools import interleave_longest
list(interleave_longest(x, y))
# returns:
['y', 'n', 'e', 'o', 's', 'p', 'e', '!']
Or if you don't want to install a new package, the source code for the function is pretty small.
from itertools import chain, zip_longest
_marker = object()
def interleave_longest(*iterables):
"""Return a new iterable yielding from each iterable in turn,
skipping any that are exhausted.
>>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8]))
[1, 4, 6, 2, 5, 7, 3, 8]
This function produces the same output as :func:`roundrobin`, but may
perform better for some inputs (in particular when the number of iterables
is large).
"""
i = chain.from_iterable(zip_longest(*iterables, fillvalue=_marker))
return [x for x in i if x is not _marker]
interleave_longest(x, y)
# returns:
['y', 'n', 'e', 'o', 's', 'p', 'e', '!']