简体   繁体   English

递归时如何使用'for in range:'修复'IndexError:list index out of range'

[英]How to fix 'IndexError: list index out of range' using 'for in range:' while recursion

I'm trying to implement 'unique_in_order' function. 我正在尝试实现“ unique_in_order”功能。 This function takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements. 此函数将序列作为参数,并返回不包含具有相同值的任何元素且彼此相邻并保留元素原始顺序的项目列表。

For example: 例如:

unique_in_order('AAAABBBCCDAABBB') == ['A', 'B', 'C', 'D', 'A', 'B']
unique_in_order('ABBCcAD')         == ['A', 'B', 'C', 'c', 'A', 'D']
unique_in_order([1,2,2,3,3])       == [1,2,3]
ets

It's the code of this function: 这是此函数的代码:

def unique_in_order(iterable):
    iterable = list(iterable)
    l_lenth = int(len(iterable))
    for i in range(0, l_lenth-1):
        if iterable[i] == iterable[i+1]:
            del iterable[i+1]
            l_lenth = l_lenth - 1
            unique_in_order(iterable)
    return(iterable)`

But if we will run this, an error occurres: 但是,如果运行此命令,则会发生错误:

    Traceback (most recent call last):
      File "test.py", line 15, in <module>
        unique_in_order(x)
      File "test.py", line 11, in unique_in_order
        unique_in_order(iterable)
      File "test.py", line 11, in unique_in_order
        unique_in_order(iterable)
      File "test.py", line 11, in unique_in_order
        unique_in_order(iterable)
      [Previous line repeated 4 more times]
      File "test.py", line 6, in unique_in_order
        if iterable[i] == iterable[i+1]:
    IndexError: list index out of range

I tried to add some 'print()' to monitor the progress: 我试图添加一些“ print()”来监视进度:

def unique_in_order(iterable):
    iterable = list(iterable)
    l_lenth = int(len(iterable))
    for i in range(0, l_lenth-1):
        if iterable[i] == iterable[i+1]:
            del iterable[i+1]
            l_lenth = l_lenth - 1
            print('sign {0} was deleted \n new list: \n{1}'.format(i+1, iterable))
            print('new lenth: {0}, i = {1}'.format(l_lenth,i))
            unique_in_order(iterable)
    print('Result: {}'.format(iterable))
x = 'AAABBBCCDAA'
print('input data: {0}\nlenth: {1}'.format(x,len(x)))
unique_in_order(x)

result: 结果:

input data: AAABBBCCDAA
lenth: 11
sign 1 was deleted
 new list:
['A', 'A', 'B', 'B', 'B', 'C', 'C', 'D', 'A', 'A']
new lenth: 10, i = 0
sign 1 was deleted
 new list:
['A', 'B', 'B', 'B', 'C', 'C', 'D', 'A', 'A']
new lenth: 9, i = 0
sign 2 was deleted
 new list:
['A', 'B', 'B', 'C', 'C', 'D', 'A', 'A']
new lenth: 8, i = 1
sign 2 was deleted
 new list:
['A', 'B', 'C', 'C', 'D', 'A', 'A']
new lenth: 7, i = 1
sign 3 was deleted
 new list:
['A', 'B', 'C', 'D', 'A', 'A']
new lenth: 6, i = 2
sign 5 was deleted
 new list:
['A', 'B', 'C', 'D', 'A']
new lenth: 5, i = 4
Result: ['A', 'B', 'C', 'D', 'A']
Result: ['A', 'B', 'C', 'D', 'A']
sign 5 was deleted
 new list:
['A', 'B', 'C', 'D', 'A']
new lenth: 5, i = 4
Result: ['A', 'B', 'C', 'D', 'A']
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    unique_in_order(x)
  File "test.py", line 11, in unique_in_order
    unique_in_order(iterable)
  File "test.py", line 11, in unique_in_order
    unique_in_order(iterable)
  File "test.py", line 11, in unique_in_order
    unique_in_order(iterable)
  [Previous line repeated 1 more time]
  File "test.py", line 6, in unique_in_order
    if iterable[i] == iterable[i+1]:
IndexError: list index out of range

So, as we can see, the result is right, but because of 'IndexError' I can't return() the output data. 因此,正如我们所看到的,结果是正确的,但是由于“ IndexError”,我无法返回()输出数据。 Additionally, the 'Result:' line is displayed two more times when i = 4(I guess in this step this problem occures). 此外,当i = 4时,“结果:”行会显示两次以上(我想在此步骤中会发生此问题)。 I would be grateful if you will help me to solve this problem. 如果您能帮助我解决这个问题,我将不胜感激。 Thanks in advance. 提前致谢。

You're going to get some pretty wacky behavior trying to delete from a list as you are iterating through it. 在遍历列表时,您将遇到一些古怪的行为,试图从列表中删除。 And I don't understand why you are recursively calling this function, you're already iterating through the entire list with a loop. 而且我不明白为什么您要递归调用此函数,您已经在循环遍历整个列表了。 This can be much simpler 这可以简单得多

def unique_in_order(iterable):
  iterable = list(iterable)
  result = [iterable[0]]
  for i in range(1, (len(iterable))-1):
    if result[len(result)-1] != iterable[i]:
      result.append(iterable[i])
  return(result)

If you really want to do it without a result list, maybe you have some crazy memory constraints, use a while loop instead of a for loop. 如果您真的想在没有结果列表的情况下执行此操作,则可能是您有一些疯狂的内存约束,请使用while循环而不是for循环。 The parameters of the exit condition for a for loop is calculated one time at the start of the loop (in this case the length of the list), but the condition of a while loop is calculated every iteration. for循环的退出条件参数在循环开始时计算一次(在这种情况下为列表的长度),但是while循环的条件在每次迭代时都会计算。

The problem is that you are iterating over the original length of the iterable. 问题是您要遍历可迭代对象的原始长度。 When you delete items form the list you shorten it. 从列表中删除项目时,将其缩短。 I can see you've tried to handle this by subtracting one from l_length but that has no effect as you've already initialised the iterable used for the for loop as range(0, l_lenth-1) . 我可以看到您尝试通过从l_length中减去一个来处理此问题,但这没有任何作用,因为您已经将for循环使用的可迭代项初始化为range(0, l_lenth-1) Changing l_lenth will make no difference after this. 此后更改l_lenth不会有任何区别。 You should use a while loop instead while i<l_lenth 您应该使用while循环而不是while i<l_lenth

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM