Python倒置列表中每两个元素。

3

我在 Python 中有一个列表,希望将列表中每对元素翻转。以下是该列表:

list_ty = ['many_ord','many','12_FH_Temp_ord','12_FH_Temp','Celsius_ord','Celsius','Pressure_Pas_ord','Pressure_Pas','Kelvin_ord','Kelvin']

以下是我想要的内容:

这里是我想要的内容:

list_out = ['many','many_ord','12_FH_Temp','12_FH_Temp_ord','Celsius','Celsius_ord','Pressure_Pas','Pressure_Pas_ord','Kelvin','Kelvin_ord']

附加信息:

列表中的元素总是偶数个。

_ord 结尾的项目总是出现在没有 _ord 的项目之前。

问题:

有没有办法反转每个以 _ord 结尾的项目及其后面(关联的)没有 _ord 的项目的顺序?


迭代列表中的一对元素是关键,有很多答案可以在https://dev59.com/MW435IYBdhLWcg3wfQF9找到。 - user4322779
5个回答

9

使用 for 循环并一次跨越 2 个元素。然后可以使用基本的 Python 变量交换:

a, b = b, a

list_ty = ['many_ord','many','12_FH_Temp_ord','12_FH_Temp','Celsius_ord','Celsius','Pressure_Pas_ord','Pressure_Pas','Kelvin_ord','Kelvin']

for i in range(0, len(list_ty), 2):
    list_ty[i], list_ty[i+1] = list_ty[i+1], list_ty[i] 

在这个循环之后,list_ty 的值如下:

['many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord', 'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord']

3
也许有点幼稚,但是这里给出一行代码:
from itertools import chain

list_out = list(chain.from_iterable(zip(list_ty[1::2], list_ty[::2])))

为了解释这段代码:我们使用步长为2,偏移量为1的切片获取奇数索引中的值,再使用步长为2,偏移量为0的切片获取偶数索引中的值。然后通过zip将它们组合在一起,使[even, odd, even, odd,...]变成((odd, even), (odd, even), ...),最后使用chain.from_iterable将那些tuple展开,并使用list生成器实现chain

2

懒人的方法:

>>> [x + y for x in list_ty if not x.endswith('_ord') for y in ('', '_ord')]
['many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord', 'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord']

忽略任何以"_ord"结尾的条目,只需将其交替添加到其他元素中。

2

有很多方法可以做到这一点,下面介绍一种使用range(len())的方法:

list_out = [list_ty[idx+2*(not idx%2)-1] for idx in range(len(list_ty))]

该代码会对原列表中的每个可能索引进行遍历,并获取该索引之前或之后的项目。

0 会获取索引 0 + 2*(not 0%2)-10 + 2*(not 0)-10 + 2*1-11 的项目。

1 会获取索引 1 + 2*(not 1%2)-11 + 2*(not 1)-11 + 2*0-10 的项目。

2 会获取索引 2 + 2*(not 2%2)-12 + 2*(not 0)-12 + 2*1-13 的项目。

3 会获取索引 3 + 2*(not 3%2)-13 + 2*(not 1)-13 + 2*0-12 的项目。

正如您所看到的那样,它不是按照原来的顺序0123,而是1032,并且这种模式将继续,直到结果完成。


1
我对此感到矛盾。一方面,idx+2*(not idx%2)-1非常晦涩,依赖于有趣的非直观行为。另一方面,我喜欢聪明的代码,即使它是作者一周后也不理解的那种聪明。 :-) - ShadowRanger
@ShadowRanger - 好的,这是我想要的算法的Python代码。我选择不使用三元运算符,但你可以使用一个,并将索引表达为 [idx-(1 if idx%2 else -1)][idx-1 if idx%2 else idx+1]。如果你认为这些更清晰明了,我很乐意将它们添加到答案中。 - TigerhawkT3
不,我没有批评的意思,那更多是一种赞美。 - ShadowRanger

2
这样怎么样:
>>> sum(zip(list_ty[1::2], list_ty[::2]), ())
('many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord',     'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord')
>>>

1
非常感谢您!我喜欢这个,它按照我的要求工作。 - edesz
如果性能是一个问题,这里有一个警告:这将构建和销毁大量的元组;由 zip 创建的两个元素的元组可以通过使用 future_builtins 中的 Py3 版本的 zip 来几乎免费地创建,但它会创建一系列长度为 2、长度为 4、长度为 6 等的元组,在 list_ty 的每一对元素中重建一次。如果已知 list 较小,则没有什么大不了的,但如果可能很长,则基本上所有其他解决方案都更优,因为它们避免在操作期间创建大量临时变量。 - ShadowRanger

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