Python &引用;索引器:列表索引超出范围“;交换列表中的元素时

Python &引用;索引器:列表索引超出范围“;交换列表中的元素时,python,list,indexing,index-error,Python,List,Indexing,Index Error,我必须编写一个函数“swaplist”,它执行以下操作: 在输入2列表中给出: 列表1,列表2 例如: [中四、中六] [4,2,3,6,5] *记住[s5]不能在输入中给出 返回一个列表,其中4与下一个数字交换,6与下一个数字交换 [2,4,3,5,6] 这是我写的代码: def swaplist(list1,list2): list3=list2 for i in list3: if ('s'+str(i)) in list1: a=l

我必须编写一个函数“swaplist”,它执行以下操作:

在输入2列表中给出:

列表1,列表2

例如:

[中四、中六]

[4,2,3,6,5]

*记住[s5]不能在输入中给出

返回一个列表,其中4与下一个数字交换,6与下一个数字交换

[2,4,3,5,6]

这是我写的代码:

def swaplist(list1,list2):
    list3=list2
    for i in list3:
        if ('s'+str(i)) in list1:
            a=list3.index(i)
            b=a+1
            list3[a],list3[b]=list3[b],list3[a]
    return list3
我尝试运行此代码,但出现以下错误:

索引器错误:列表索引超出范围

有人知道怎么解决这个问题吗

谢谢你们抽出时间

  • 对不起,我的英语不好

    • 这看起来像是一个家庭作业问题

      问题是您正在更改与正在迭代的列表相同的列表。解决方案的第一步是遍历列表2并在列表3中进行更改。这样,当您第一次遇到
      4
      时,您可以向右交换它。但是,您在列表3中遇到的下一个项目再次是
      4
      ,您再次交换它。这种情况会一直持续下去,直到您到达列表3的末尾,并在尝试交换
      4
      时出错

      但是,另一个问题出现了:仅仅设置
      list3=list2
      并不能真正创建一个新列表。列表3和列表2都指向同一个列表

      为了帮助查看正在发生的事情,您可以使用调试器逐步完成代码。由于这是一段相当短的代码,您还可以添加显示变量值和列表的
      print
      语句。例如:

      def swaplist(list1,list2):
          list3=list2
          for i in list3:
              print("i:", i)
              if ('s'+str(i)) in list1:
                  a=list3.index(i)
                  b=a+1
                  list3[a],list3[b]=list3[b],list3[a]
                  print('s' + str(i), a, b, "list is now:", list3)
          return list3
      
      *扰流板* 然而,要真正解决您的问题,您需要将列表3作为一个全新的列表。对于非常复杂的结构,您需要一个深度副本,并且有库函数来创建这样的
      deepcopy
      。对于一个简单的列表,可以通过再次遍历列表来创建副本。或者使用其他人提到的
      copy()
      功能

      def swaplist(list1,list2):
          list3=[i for i in list2]
          for i in list2: # note we are looping through list2 and changing list3
              print("i:", i)
              if ('s'+str(i)) in list1:
                  a=list3.index(i)
                  b=a+1
                  list3[a],list3[b]=list3[b],list3[a]
                  print('s' + str(i), a, b, "list is now:", list3)
          return list3
      

      您在对列表进行迭代时正在修改列表,这将导致不必要的行为

      如果我们每次交换一个数字时都进行
      print(list3)
      ,我们可以看到循环时列表发生了什么

      在检查列表中的第一个数字后,我们看到它是一个4,应该进行交换。列表是
      [4,2,3,5,6]
      ,现在是
      [2,4,3,5,6]

      让我们转到列表中的第二个数字。因为您修改了原始列表,所以第二个数字现在是4,将与下一个数字交换

      这是程序在每次交换后打印的内容:

      [2, 4, 3, 5, 6]
      [2, 3, 4, 5, 6]
      [2, 3, 5, 4, 6]
      [2, 3, 5, 6, 4]
      
      您的编号4将被移动到列表中的下一个位置,然后再次检查

      解决这个问题的方法是构造一个新列表,而不是修改原始列表。大概是这样的:

      def swaplist(list1,list2):
          # Make a copy of the original list so we don't modify it.
          # Use a more verbose name for the list so it's clear what the purpose is
          result_list=list2.copy()
      
          # Use enumerate to get both the index (i), as well as the list item in one go.
          for i, item in enumerate(list2):
              if ('s'+str(item)) in list1:
                  # Swap the values using the original list as source.
                  result_list[i],result_list[i+1]=list2[i+1],list2[i]
          return result_list
      

      正如JohanC所提到的,问题在于你改变了你循环的列表。 您可以先复制列表2,然后只更改列表3

      def swaplist(list1,list2):
          list3=list2.copy()
          for i in list2:
              print(i)
              if f's{i}' in list1:
                  a=list3.index(i)
                  b=a+1
                  list3[a],list3[b]=list3[b],list3[a]
          return list3