简体   繁体   English

迭代时替换列表中的项目

[英]replacing item in list while iterating

From Google's Python Class 来自Google的Python类

#!/usr/bin/python -tt
# Copyright 2010 Google Inc.
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Google's Python Class
# http://code.google.com/edu/languages/google-python-class/

# Additional basic list exercises

# D. Given a list of numbers, return a list where
# all adjacent == elements have been reduced to a single element,
# so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or
# modify the passed in list.
def remove_adjacent(nums):
  x = 0
  newlist = []
  for x in range(0,len(nums),1):
    if nums[x] == nums[x+1]:
      newlist.append(nums[x])
      x = x+2
    else:
      newlist.append(nums[x])
      x = x+1

  return nums

it is giving me an error saying that the list index is out of range but I am not sure what is wrong. 它给我一个错误,说列表索引超出范围,但我不确定是什么问题。 I read somewhere that you cannot replace values in a list while iterating using a for loop but have no idea how to fix that. 我在某处读到,在使用for循环迭代时无法替换列表中的值,但不知道如何解决这个问题。 Any advice would be appreciated. 任何意见,将不胜感激。

Its probably due to nums[x+1] being out of range. 这可能是因为nums[x+1]超出了范围。 x only goes from 0 to len(nums) - 1 meaning that when x is len(nums)-1 , you will essentially be indexing into nums[len(nums)] which will be one past the end of nums (remember the last index in a non-empty list is 1 less than its length, since we start counting indexes from 0 ). x只从0len(nums) - 1意味着当xlen(nums)-1 ,你将基本上索引到nums[len(nums)] ,这将是nums结束之后的一个(记住最后一个)非空列表中的索引比其长度小1 ,因为我们从0开始计算索引。

The index x+1 will be out of range when x is the index of the very last element. 当x是最后一个元素的索引时,索引x+1将超出范围。 In addition, you are creating a new list yet you return the old one. 此外,您正在创建一个新列表,但是您将返回旧列表。

Modifying the value of x isn't doing what you think as it is being reset at every loop iteration. 修改x的值并没有按照您的想法进行,因为它在每次循环迭代时都会被重置

Here is an alternative implementation: 这是一个替代实现:

def remove_adjacent(nums):
  newlist = []
  for i in range(0, len(nums)):
    if i == len(nums) - 1:      # Avoid out of range error.
      newlist.append(nums[i])
    elif nums[i] == nums[i+1]:  # Skip until the last repeat
      continue
    else:  
      newlist.append(nums[i])
  return newlist    

You can also do this using zip and list comprehension: 你也可以使用zip和list comprehension来做到这一点:

def remove_adjacent(nums):
    return [n[0] for n in zip(nums, nums[1:]) if n[0] != n[1]]

The index x+1 goes out of range on the last element of the list, whose index is len(nums)-1 -- there is no nums[len(nums)] . 索引x+1超出了列表最后一个元素的范围,其索引是len(nums)-1 - 没有nums[len(nums)]

It would be really simple to just use the groupby() function in the itertools module: itertools模块中使用groupby()函数非常简单:

from itertools import groupby

def remove_adjacent(nums):
    return [k for k, _ in groupby(nums)]

print remove_adjacent([1, 2, 2, 2, 3])

Output: 输出:

[1, 2, 3]

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

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