重新排列字符串列表

Rearrange a list of strings

我想重新排列或修改列表中的元素(字符串)序列。这是原始列​​表

['A', 'B', 'C', 'D', 'E', 'F', 'G']

我想将 EF 移到 B.B.

后面(或之后?)
['A', 'B', 'E', 'F', 'C', 'D', 'G']
           ^^^  ^^^

移动什么由用户决定。背后没有规则,也没有办法在算法中制定它。换句话说,将某些东西移到其他东西后面 是用户输入的动作;例如用户用 her/his 鼠标标记两个元素并将其拖放到另一个元素后面。

我的代码有效并且能够做到这一点。但我想知道是否有更有效和 pythonic 的方式来做到这一点。也许我错过了 Python 的一些不错的内置功能。

#!/usr/bin/env python3
# input data
original = list('ABCDEFG')

# move "EF" behind "B" (this is user input)
to_move = 'EF'
behind = 'B'

# expected result
rearanged = list('ABEFCDG')

# index for insertion
idx_behind = original.index(behind)

# each element to move
for c in reversed(to_move):  # "reverse!"
    # remove from original position
    original.remove(c)
    # add to new position
    original.insert(idx_behind + 1, c)

# True
print(original == rearanged)

你可以假设

其他可能的例子输入:

这是不可能的:

如果您只是想重新排列少量项目,只需交换相关元素即可:

lst = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
lst[2], lst[4] = lst[4], lst[2]  # switch 'C' and 'E'
lst[3], lst[5] = lst[5], lst[3]  # switch 'D' and 'F'

lst
['A', 'B', 'E', 'F', 'C', 'D', 'G']
  1. 当目标是从特定位置擦除时,不要使用.remove;虽然您可能知道那个位置是什么,但 .remove a) 将再次搜索它,并且 b) 删除 first 出现的地方,这不一定是您在介意。

  2. 如果要删除多个连续元素,请不要一次删除一个元素;这就是切片存在的原因,也是 del 运算符以其方式工作的原因。当您可以直接说出您想要的内容时,不仅迭代已经变得更加困难,而且您还必须注意 modifying a list while iterating over it.

    的常见问题
  3. 如果要添加多个连续的元素,请不要一次添加一个元素;相反,insert them all at once by slice assignment。同样的原因也适用于此。

  4. 尤其不要试图交错插入和移除操作。这比必要的复杂得多,如果插入位置与源位置重叠,可能会导致问题。

因此:

original = list('ABCDEFG')
start = original.index('E')
# grabbing two consecutive elements:
to_move = original[start:start+2]
# removing them:
del original[start:start+2]
# now figure out where to insert in that result:
insertion_point = original.index('B') + 1
# and insert:
original[insertion_point:insertion_point] = to_move