我有一段代码如下:
ascii_key = [None]*(len(ascii_username) + len(ascii_password))
ascii_key[0::2] = ascii_username
ascii_key[1::2] = ascii_password
我不断收到以下错误:
值错误:尝试将大小为 8 的序列分配给大小为 6 的扩展切片
我认为这与它希望我准确地填写整个扩展列表的事实有关,如果是这样的话,有没有办法在它生气之前将两个列表结合起来?
理想的过程是列出["A", "B", "C"]
,["D", "E", "F"]
成为
["A", "D", "B", "E", "C", "F"]
我尝试按照这篇文章中的解决方案 Pythonic 方式以交替的方式组合两个列表?
-提前道歉,我是一名新手程序员。
您要做的是两个序列的交错。 您看到错误的原因是ascii_username
和ascii_password
的长度不同。 当您尝试分配给列表的切片时,您必须提供切片中元素的确切数量。
在这个例子中很容易看出:步长为 2 的切片x
的元素多于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']
尝试分配给x[::2]
会留下一个悬而未决的7
,该不会重新分配。
若要解决此问题,可以使用more_itertools
包中的interleave_longest
。
from more_itertools import interleave_longest
list(interleave_longest(x, y))
# returns:
['y', 'n', 'e', 'o', 's', 'p', 'e', '!']
或者,如果您不想安装新软件包,则该函数的源代码非常小。
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', '!']
对于该任务,您可以使用roundrobin
,如 itertools recipes 所示
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
然后:
t1 = ['A', 'B', 'C']
t2 = ['D', 'E', 'F']
interleaved = list(roundrobin(t1,t2))
print(interleaved) # ['A', 'D', 'B', 'E', 'C', 'F']
请注意,由于roundrobin(t1,t2)
是生成器,我将其输入list
函数以获取list
。它将使用所有元素,例如用于t1 = ['A', 'B', 'C']
,t2 = ['D', 'E', 'F', 'G', 'H']
结果是['A', 'D', 'B', 'E', 'C', 'F', 'G', 'H']
。