尝试通过交替值组合列表时卡在扩展切片上
Stuck on extended slices when attempting to combine lists by alternating values
我有一段代码如下:
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"]
我尝试按照此 post Pythonic way to combine two lists in an alternating fashion?
中的解决方案
-提前致歉,我是新手程序员。
对于该任务,您可以使用 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']
.
你要做的是交织两个序列。您看到错误的原因是 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', '!']
我有一段代码如下:
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"]
我尝试按照此 post Pythonic way to combine two lists in an alternating fashion?
中的解决方案-提前致歉,我是新手程序员。
对于该任务,您可以使用 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']
.
你要做的是交织两个序列。您看到错误的原因是 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', '!']