在Python中创建另一个列表中相邻元素的列表

2024-05-12 20:14:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望将一个列表作为输入,然后创建另一个列表,该列表包含原始列表中相邻元素的元组(或子列表),并环绕开始和结束元素。输入/输出如下所示:

l_in  = [0, 1, 2, 3]
l_out = [(3, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, 0)]

我的问题与另一个名为getting successive adjacent elements of a list的问题密切相关,但这另一个问题没有考虑结束元素的包装,只处理成对的元素,而不是三元组。在

我有一种更长的方法来完成这项工作,包括旋转deques并将它们压缩在一起:

^{pr2}$

但是,我觉得可能有一种更优雅(和/或更高效)的方法来使用其他内置的Python功能来实现这一点。例如,如果dequerotate()函数返回了经过旋转的列表,而不是对其进行适当的修改,那么这可能是一个或两个行程序(尽管这种压缩旋转列表的方法可能不是最有效的)。我如何才能更优雅和/或更有效地完成这项工作?在


Tags: of方法in元素列表elementsoutlist
3条回答

好吧,我在写问题的时候找到了一个更好的解决方案,但我已经完成了写问题的工作,所以就这样。这个解决方案至少要简洁得多:

l_out = list(zip(l_in[-1:] + l_in[:-1], l_in, l_in[1:] + l_in[:1]))

有关如何在Python中旋转列表的不同答案,请参见this post。在

上面的一行解决方案至少应该和问题中的解决方案一样有效(根据我的理解),因为切片不应该比deques的旋转复制更昂贵(参见https://wiki.python.org/moin/TimeComplexity)。在

不过,其他更有效(或优雅)解决方案的答案仍然受到欢迎。在

一种方法是将^{}^{}结合使用:

import itertools as it

import more_itertools as mit


l_in  = [0, 1, 2, 3]
n = len(l_in)
list(it.islice(mit.windowed(it.cycle(l_in), 3), n-1, 2*n-1))
# [(3, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, 0)]

在这里,我们生成了一个sliding windows的无限循环,并切片了所需的子集。在


FWIW,这里是后一个代码的抽象,对于给定任何iterable输入的通用、灵活的解决方案,例如range(5)"abcde"iter([0, 1, 2, 3])等:

^{pr2}$

注意:^{}是一个单独的库,可以通过以下方式轻松安装:

^{3}$

这可以通过切片来完成:

l_in  = [0, 1, 2, 3]

l_in = [l_in[-1]] + l_in + [l_in[0]]
l_out = [l_in[i:i+3] for i in range(len(l_in)-2)]

好吧,或者是这样的变态:

^{pr2}$

可以指定迭代次数。在

相关问题 更多 >