首页 > 解决方案 > 在迭代期间交换列表元素

问题描述

我在几个地方读到过,在迭代期间修改数组/列表是不好的做法。然而,许多常见的算法似乎可以做到这一点。例如冒泡排序、插入排序和下面的示例,用于查找对列表进行排序所需的最小交换次数。

在迭代期间交换列表项是否是规则的例外?如果是,为什么?

enumerate在这方面发生的事情和简单的for i in range(len(arr))循环之间有区别吗?

def minimumSwaps(arr):
    ref_arr = sorted(arr)
    index_dict = {v: i for i,v in enumerate(arr)}
    swaps = 0
    
    for i,v in enumerate(arr):
        print("i:", i, "v:", v)
        print("arr: ", arr)
        correct_value = ref_arr[i]
        if v != correct_value:
            to_swap_ix = index_dict[correct_value]
            print("swapping", arr[to_swap_ix], "with", arr[i])
            # Why can you modify list during iteration?
            arr[to_swap_ix],arr[i] = arr[i], arr[to_swap_ix]
            index_dict[v] = to_swap_ix
            index_dict[correct_value] = i
            swaps += 1
            
    return swaps
    

arr = list(map(int, "1 3 5 2 4 6 7".split(" ")))
assert minimumSwaps(arr) == 3

标签: pythonlistiteration

解决方案


遍历数组时不应修改数组,因为迭代器无法处理更改。但是还有其他方法可以在不使用迭代器的情况下遍历数组。

这是使用迭代器:

for index, item in enumerate(array):
   # don't modify array here

这是没有迭代器的:

for index in range(len(array)):
   item = array[index]
   # feel free to modify array, but make sure index and len(array) are still OK

如果在修改数组时需要修改长度和索引,请更“手动”进行:

index = 0
while index < len(array):
   item = array[index]
   # feel free to modify array and modify index if needed
   index += 1

推荐阅读