尝试通过交替值合并列表时卡在扩展切片上



我有一段代码如下:

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_usernameascii_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']

最新更新