重新排列字符串列表
Rearrange a list of strings
我想重新排列或修改列表中的元素(字符串)序列。这是原始列表
['A', 'B', 'C', 'D', 'E', 'F', 'G']
我想将 E
和 F
移到 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)
你可以假设
original
中的元素是唯一的。
to_move
总是存在于 original
.
behind
总是存在于 original
.
to_move
中的元素始终相邻。
其他可能的例子输入:
- 将
['B']
移到F
后面
- 将
['A', 'B']
移到C
后面
这是不可能的:
- 将
['A', 'F']
移到D
后面
如果您只是想重新排列少量项目,只需交换相关元素即可:
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']
当目标是从特定位置擦除时,不要使用.remove
;虽然您可能知道那个位置是什么,但 .remove
a) 将再次搜索它,并且 b) 删除 first 出现的地方,这不一定是您在介意。
如果要删除多个连续元素,请不要一次删除一个元素;这就是切片存在的原因,也是 del
运算符以其方式工作的原因。当您可以直接说出您想要的内容时,不仅迭代已经变得更加困难,而且您还必须注意 modifying a list while iterating over it.
的常见问题
如果要添加多个连续的元素,请不要一次添加一个元素;相反,insert them all at once by slice assignment。同样的原因也适用于此。
尤其不要试图交错插入和移除操作。这比必要的复杂得多,如果插入位置与源位置重叠,可能会导致问题。
因此:
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
我想重新排列或修改列表中的元素(字符串)序列。这是原始列表
['A', 'B', 'C', 'D', 'E', 'F', 'G']
我想将 E
和 F
移到 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)
你可以假设
original
中的元素是唯一的。to_move
总是存在于original
.behind
总是存在于original
.to_move
中的元素始终相邻。
其他可能的例子输入:
- 将
['B']
移到F
后面
- 将
['A', 'B']
移到C
后面
这是不可能的:
- 将
['A', 'F']
移到D
后面
如果您只是想重新排列少量项目,只需交换相关元素即可:
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']
当目标是从特定位置擦除时,不要使用
.remove
;虽然您可能知道那个位置是什么,但.remove
a) 将再次搜索它,并且 b) 删除 first 出现的地方,这不一定是您在介意。如果要删除多个连续元素,请不要一次删除一个元素;这就是切片存在的原因,也是
的常见问题del
运算符以其方式工作的原因。当您可以直接说出您想要的内容时,不仅迭代已经变得更加困难,而且您还必须注意 modifying a list while iterating over it.如果要添加多个连续的元素,请不要一次添加一个元素;相反,insert them all at once by slice assignment。同样的原因也适用于此。
尤其不要试图交错插入和移除操作。这比必要的复杂得多,如果插入位置与源位置重叠,可能会导致问题。
因此:
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