以最小的方式扩展列表n个元素

10

我想要扩展一个列表

[1,2,3,4]

n 提供

例如,当 n = 2 时:

[1,1,2,2,3,3,4,4]
我正在寻找最小可能的方法来实现这一点,不使用任何额外的库。 可以通过循环并将每个项目n次附加到新列表中轻松完成...但是是否还有其他方法?

@jamylak itertools 是标准库中的一部分,因此不使用它是愚蠢的。 - Gareth Latty
另外,您希望它如何运作?在这种情况下,它是不可变对象,但对于可变对象应该如何运作? - Gareth Latty
你所说的“最小”是指代码长度/美观度还是执行时间? - Max Li
@Schinken 好的,我发布了一个解决方案,它似乎在其他解决方案中具有最小的长度。 - Max Li
8个回答

13
>>> l = [1,2,3,4]
>>> [it for it in l for _ in range(2)]
[1, 1, 2, 2, 3, 3, 4, 4]

2
这里有一个关于可变对象的警告。如果你让l等于[1, 2, [3]],然后按照你的方法操作,再执行test2[4].append(4),你会得到[1, 1, 2, 2, [3, 4], [3, 4]]。显然,在大多数情况下这不会是个问题,但值得注意。 - Gareth Latty
它将在Python 2.x和3.x中工作 - 问题在于您只是对同一项有两个引用,因此当您更新其中任何一个时,另一个也会更新。 - Gareth Latty

5

2
哇,虽然我很喜欢itertools,但这让我头疼。 - Tim Pietzcker
@TimPietzcker,我发现这篇文章比hamstergene的回答更容易阅读。 - Marcin
@jamylak,你认为izip、tee和chain来自哪里? - Marcin
展开 = 列表(chain(*izip(*tee(l, n)))) - jamylak
@Marcin,这让您可以在不显示它们的情况下进行快速编辑。我也看过旧版。 - Gareth Latty
显示剩余4条评论

4

我在评论中已经记录了这一点,但如果能用答案解释,那会更容易,因为我可以给出完整的代码示例。请注意,这只是一个特定情况下的修改版本,更多的是作为其他回答的补充,而不是独立的完整回答。

如果您需要处理可变对象,则使用此处介绍的其他方法会遇到问题:

>>> l = [1,2,3,[4]]
>>> test = [it for it in l for _ in range(2)]
>>> test
[1, 1, 2, 2, 3, 3, [4], [4]]
>>> test[6].append(5)
>>> test
[1, 1, 2, 2, 3, 3, [4, 5], [4, 5]]

因此,如果您想避免这种行为,您需要使用copy.deepcopy()
>>> import copy
>>> l = [1,2,3,[4]]
>>> test = [copy.deepcopy(it) for it in l for _ in range(2)]
>>> test
[1, 1, 2, 2, 3, 3, [4], [4]]
>>> test[6].append(5)
>>> test
[1, 1, 2, 2, 3, 3, [4, 5], [4]]

当然,这只适用于列表中可变对象,并且只有在您预计它们在创建新列表后会更改时才需要使用。


2
>>> from itertools import chain, tee
>>> x = [1, 2, 3, 4]
>>> n = 2
>>> list(chain.from_iterable(zip(*tee(x, n))))
[1, 1, 2, 2, 3, 3, 4, 4]

1
你为什么复制了另一个答案? - Marcin
我只看到了他的旧版本,就像我在评论中所说的那样,这是我自己想出来的。如果你想要的话,可以删除它。 - jamylak

2
sum([[x]*2 for x in l],[])

其中l是您的列表


所以,为了将元素重复三次,我必须写sum([[x,x,x] for x in l],[])吗?这似乎不太方便。 - Felix Kling
1
或者可以改为:sum([[x]*3 for x in l],[]) - jamylak
@FelixKling:请看jamylak的评论,了解我在回答中留下的隐含意思。虽然我猜想既然OP想要“n”而不是2,那么我会将其从“[x,x]”更改为“n”。 - ninjagecko

0

由于问题的作者在评论中回答说“最小可能的方式”是指代码长度最小,因此我敢于发布以下解决方案:

>>> sorted([1,2,3,4]*2)
[1, 1, 2, 2, 3, 3, 4, 4]

它的长度为19。


0
>>> from itertools import repeat, chain
>>> seq = [1, 2, 3, 4]
>>> list(chain.from_iterable(repeat(x, 2) for x in seq))
[1, 1, 2, 2, 3, 3, 4, 4]

0
>>> from itertools import chain
>>> seq = [1, 2, 3, 4]
>>> list(chain.from_iterable(zip(*[seq]*2)))
[1, 1, 2, 2, 3, 3, 4, 4]
>>> list(chain.from_iterable(zip(*[seq]*6)))
[1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接