首页 > 解决方案 > 尝试通过交替值组合列表时卡在扩展切片上

问题描述

我有一段代码如下:

ascii_key = [None]*(len(ascii_username) + len(ascii_password))
ascii_key[0::2] = ascii_username
ascii_key[1::2] = ascii_password

我不断收到以下错误:

ValueError:尝试将大小为 8 的序列分配给大小为 6 的扩展切片

我认为这与它希望我准确填写整个扩展列表这一事实有关,如果是这种情况,是否有办法在它发疯之前将这两个列表结合起来?

理想的过程是列出["A", "B", "C"]["D", "E", "F"]成为

["A", "D", "B", "E", "C", "F"]

我尝试按照这篇Pythonic 方式的解决方案以交替方式组合两个列表?

- 提前道歉,我是一个新手程序员。

标签: pythonlistsequenceslice

解决方案


您正在尝试做的是两个序列的交错。您看到错误的原因是因为ascii_username长度ascii_password不同。当您尝试分配给列表的切片时,您必须提供切片中元素的确切数量。

在这个例子中很容易看出:x以 2 步长进行切片的元素比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未重新分配的悬空。

要解决此问题,您可以interleave_longestmore_itertools包中使用。

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', '!']

推荐阅读