在列表中交换两个子列表

so.*_*red 18 python list

鉴于以下列表:

my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)

我希望能够尽可能快速有效地将子列表my_list[2:4]与子列表交换my_list[7:10],以获得新列表:

new_list=[0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

def swap(s1, s2, l):

    seg1=l[:s1.start]+l[s2]
    seg2=l[s1.stop : s2.start]
    seg3=l[s1]+l[s2.stop:]

    return seg1+seg2+seg3


print swap(slice(2,4), slice(7,10), [0,1,2,3,4,5,6,7,8,9,10,11,12])
Run Code Online (Sandbox Code Playgroud)

这确实打印了所需的输出,虽然这样做对我来说很糟糕.

是否有一种更简单,更优雅的方式,不会为每个函数调用创建四个新列表?(我打算多打电话给这个功能)

我不介意(实际上我更喜欢)更改原始列表,而不是每个函数调用创建新实例.

ffe*_*rri 28

可以分配切片.

可以交换两个变量a, b = b, a.

结合上面的两个::

>>> my_list[7:10], my_list[2:4] = my_list[2:4], my_list[7:10]
>>> my_list
[0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)

请注意 - 如果切片具有不同的大小 - 顺序很重要:如果以相反的顺序交换,最终会得到不同的结果,因为它将首先更改初始项(较低的索引),然后更高的索引项(但是第一次任务将把它们转移到不同的位置).

此外,切片不得重叠.

  • 是的,你不能以相反的顺序交换列表.如果使用函数,我们可以先判断两个范围的边界. (3认同)

int*_*jay 5

您可以x,y = y,x在此处使用常规交换技术(),但前提是x必须以正确的顺序执行交换:必须是第二个(最右边)片,而y第一个是(最左边)片。

>>> my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> my_list[7:10], my_list[2:4] = my_list[2:4], my_list[7:10]
>>> my_list
[0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12]
Run Code Online (Sandbox Code Playgroud)

之所以有效,是因为它将my_list[7:10]首先分配给,然后才分配给my_list[2:4]

如果以相反的顺序执行此操作,则my_list[2:4] 由于子列表的长度不同,因此分配给first将更改项目在右侧的位置,这将导致错误的结果。

从性能角度来看,这可能比您的代码快,也可能不会比您的代码快:这可能取决于列表和切片的长度。您必须在典型的用例上对其进行测试才能看到。