Python 交错2个长度不等的列表
我希望能够交错两个可能长度不等的列表。我得到的是:Python 交错2个长度不等的列表,python,list,for-loop,indexing,Python,List,For Loop,Indexing,我希望能够交错两个可能长度不等的列表。我得到的是: def interleave(xs,ys): a=xs b=ys c=a+b c[::2]=a c[1::2]=b return c 这对于长度相等或仅为+/-1的列表非常有效。但是如果让我们假设xs=[1,2,3]和ys=[hi,bye,no,yes,why]出现以下消息: c[::2]=a ValueError: attempt to assign sequence of size 3
def interleave(xs,ys):
a=xs
b=ys
c=a+b
c[::2]=a
c[1::2]=b
return c
这对于长度相等或仅为+/-1的列表非常有效。但是如果让我们假设xs=[1,2,3]和ys=[hi,bye,no,yes,why]出现以下消息:
c[::2]=a
ValueError: attempt to assign sequence of size 3 to extended slice of size 4
如何使用索引来解决这个问题?还是必须使用for循环?
编辑:我想让额外的值只出现在末尾。您可以在此处使用:
使用来自的循环配方,此处不需要sentinel值:
from itertools import *
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
演示:
您可以在此处使用:
使用来自的循环配方,此处不需要sentinel值:
from itertools import *
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
演示:
您可以使用heapq.merge:
这样就避免了对sentinel值和平坦化的需要
请改用,以更有效地实现这一点,而不使项目具有可比性。您可以使用heapq.merge:
这样就避免了对sentinel值和平坦化的需要
相反,使用更有效的方法来实现这一点,而无需让项目具有可比性。好的,下面是我的条目:
>>> from itertools import chain
>>> xs = [1,2,3]
>>> ys = ["hi","bye","no","yes","why"]
>>> xi, yi = iter(xs), iter(ys)
>>> list(chain.from_iterable(zip(xi, yi))) + list(xi) + list(yi)
[1, 'hi', 2, 'bye', 3, 'no', 'yes', 'why']
或者
>>> [i for row in zip(xi, yi) for i in row] + list(xi) + list(yi)
这也行得通,这就是@hcwhsa使用的listcomp扁平化的习惯用法。我的第一个想法是
>>> list(zip(*sorted(list(enumerate(xs)) + list(enumerate(ys)))))[1]
(1, 'hi', 2, 'bye', 3, 'no', 'yes', 'why')
但这只是@Jon Clements的一个效率低得多的版本。我使用了一个效率低的排序,他使用了一个高效的堆队列
[我一直在尝试使用cycle working获得一些东西,但似乎并不像我希望的那么简单:结果证明我只是在努力重新实现@hcwsha发布的循环食谱,所以没有必要完成它。:^]好的,这是我的条目:
>>> from itertools import chain
>>> xs = [1,2,3]
>>> ys = ["hi","bye","no","yes","why"]
>>> xi, yi = iter(xs), iter(ys)
>>> list(chain.from_iterable(zip(xi, yi))) + list(xi) + list(yi)
[1, 'hi', 2, 'bye', 3, 'no', 'yes', 'why']
或者
>>> [i for row in zip(xi, yi) for i in row] + list(xi) + list(yi)
这也行得通,这就是@hcwhsa使用的listcomp扁平化的习惯用法。我的第一个想法是
>>> list(zip(*sorted(list(enumerate(xs)) + list(enumerate(ys)))))[1]
(1, 'hi', 2, 'bye', 3, 'no', 'yes', 'why')
但这只是@Jon Clements的一个效率低得多的版本。我使用了一个效率低的排序,他使用了一个高效的堆队列
[我一直在尝试使用cycle working获得一些东西,但似乎并不像我希望的那么简单:而且事实证明,我只是在努力重新实现@hcwsha发布的循环食谱,所以没有必要完成它。:^]保持简单:
def interleave(xs,ys):
stop = min(len(xs), len(ys))
suffix = max(xs, ys, key = len)[stop:]
out = list()
for pair in zip(xs, ys):
out.extend(pair)
out.extend(suffix)
return out
注意事项:
Python 2.7
假设列表作为参数传递。保持简单:
def interleave(xs,ys):
stop = min(len(xs), len(ys))
suffix = max(xs, ys, key = len)[stop:]
out = list()
for pair in zip(xs, ys):
out.extend(pair)
out.extend(suffix)
return out
注意事项:
Python 2.7
假设列表作为参数传递。您希望发生什么?输出应该是什么?@DavidRobinson我想做的是在末尾显示额外的值。那么[1,嗨,2,再见,3,不,是的,为什么]?@DavidRobinson是的,这是一个测验问题吗?你想发生什么?输出应该是什么?@DavidRobinson我想做的是让额外的值出现在末尾。那么[1,嗨,2,再见,3,不,是的,为什么]?@DavidRobinson是的,这是一个测验问题吗?我有一个zip函数,我制作了它来压缩X和Y。我可以用它来代替吗?@user2829177 izip_longest与zip稍有不同,zip将输出截短到最短的列表。有更简单的方法吗?@user2829177您可能会发现itertools中的循环法有点帮助。我已经在我的回答中发布了。@user2829177查看DSM的第一个解决方案,IMO这是最简单的方法。我有一个zip函数,我制作了它,可以将xs和ys分开。我可以用它来代替吗?@user2829177 izip_longest与zip稍有不同,zip将输出截短到最短的列表。有更简单的方法吗?@user2829177您可能会发现itertools中的循环法有点帮助。我已经在我的回答中发布了。@user2829177查看DSM的第一个解决方案,IMO这是最简单的方法。实际上,我们正在Python房间里讨论这一点-在Python 3.x上,我们的方法会因为需要进行比较而中断…:@乔恩·克莱门茨:嘿,我的官方条目会有效的,那里没有比较^是 啊我注意到我还重新编写了一个非itertools版本的roundrobin:我们实际上在Python房间里聊了一会儿——在Python 3.x上,我们的方法会因为需要进行比较而中断@乔恩·克莱门茨:嘿,我的官方条目会有效的,那里没有比较^是 啊我注意到我还重新编写了一个非itertools版本的循环:我认为您的out+=xs[index]+ys[index]行需要是out+=[xs[index],ys[index]],或者使用单元素切片或其他方法来确保连接列表。Python3中没有xrange。但是这些问题很容易解决。@DSM,我在一个测试用例上尝试了它,它工作了,interleavelist'ab',list'cdefghijklmnop'。我应该声明我的答案是Python 2吗?这里是否有一个假设,除非另有说明,否则答案是3?您的测试用例有点特殊,因为它们是一个字符串。试试[1,2,3]和['hi','bye','no','yes','why'],甚至['ab','cd','ef','gh']。至于Python3,我很抱歉-我确信这个问题有Python3标记,但它似乎没有。谢谢你的提示。固定的当修理
如果我不允许使用除len、range、list、str、print和.append以外的任何函数,该怎么办?我有一个求最小值的函数,所以我修正了它。但我不明白如何替换.extend@wwiiI。我认为您的out+=xs[index]+ys[index]行需要是out+=[xs[index],ys[index]],或者使用单元素切片或其他方法来确保连接列表。Python3中没有xrange。但是这些问题很容易解决。@DSM,我在一个测试用例上尝试了它,它工作了,interleavelist'ab',list'cdefghijklmnop'。我应该声明我的答案是Python 2吗?这里是否有一个假设,除非另有说明,否则答案是3?您的测试用例有点特殊,因为它们是一个字符串。试试[1,2,3]和['hi','bye','no','yes','why'],甚至['ab','cd','ef','gh']。至于Python3,我很抱歉-我确信这个问题有Python3标记,但它似乎没有。谢谢你的提示。固定的在修复时,提醒我已经看到了一些东西。如果不允许我使用除:len、range、list、str、print和.append以外的任何函数,该怎么办?我有一个求最小值的函数,所以我修正了它。但我不明白如何替换.extend@wwiit,因为它已经深入到我的思想中,不修改使用for循环迭代的序列的内容。如果你不知道自己在做什么,就不要这样做?我想弄明白为什么这个发电机没问题,有什么提示吗?@wwii这不是个好主意。把这归咎于晚上11点的一篇累帖。它将适用于2个序列。然而,对于连续等长的一个较短的一个之前-下一个项目的顺序变得不稳定-使用roundroubin配方是正确的方法做到这一点。。。我已经删除了代码,并更新了相应的答案。我被灌输了不修改使用for循环迭代的序列内容的思想。如果你不知道自己在做什么,就不要这样做?我想弄明白为什么这个发电机没问题,有什么提示吗?@wwii这不是个好主意。把这归咎于晚上11点的一篇累帖。它将适用于2个序列。然而,对于连续等长的一个较短的一个之前-下一个项目的顺序变得不稳定-使用roundroubin配方是正确的方法做到这一点。。。我已经删除了代码并更新了相应的答案。