【问题标题】:Decrement the Variable I'm Incrementing in for loop减少我在 for 循环中递增的变量
【发布时间】:2014-09-10 21:51:43
【问题描述】:

有点像 Python 的新手,我环顾四周,但没有找到满意的答案。我正在做一些练习题,我想制作一种方法来消除列表中的重复值。到目前为止,这是我的代码:

def noDouble(nums):
  for x in xrange(len(nums) - 2):
      if nums[x] == nums[x + 1]:
          nums.pop(x)
          x -= 1
  return nums

我想要发生的是,如果有重复,弹出其中一个重复,然后再次移回(这样,如果有 3 个相同数字的实例,它将摆脱所有他们通过'倒带')。

我正在寻找解释为什么我的代码不能像解释的解决方案一样工作的解释,我非常感谢任何和所有的帮助。谢谢。

【问题讨论】:

    标签: python list loops increment decrement


    【解决方案1】:

    因为for 不计算数字;它迭代一个序列。每次循环体执行时,x 被设置为xrange 产生的下一个值。 for 语句并不关心循环末尾的 x 是什么。

    无论如何,您真的不应该在循环中修改列表。更简单的方法是建立一个新列表:

    def remove_doubles(old):
        new = []
        for item in old:
            if new and item == new[-1]:
                continue
            new.append(item)
        return new
    

    当然,真正删除重复的简单方法是list(set(foo))。但这将删除所有重复项,而不仅仅是相邻的,并且可能还会破坏项目顺序。

    【讨论】:

    • 请注意,set 会给出与 OP 代码看起来不同的行为。他的方法(如果可行的话)是仅将每个元素与下一个元素进行比较,因此它只会折叠连续的重复序列,但set 将删除所有重复。不过,目前尚不清楚这里实际需要什么行为。
    • continue 跳到循环的下一个运行; item == new[-1] 检查item 是否等于new 列表中的最后一项。
    • @Eevee,为什么需要new?为什么有 and 声明的第一部分?
    • 因为如果new 为空,则没有最后一项可比较。
    • itertools.groupby 的存在可能值得注意。 [val for val, group in groupby(nums)] 构建一个新列表,其中任何重复组折叠成单个元素的出现。
    【解决方案2】:

    据我了解,for 循环不像在 C 或 Java 中那样是一个简单的增量。 Python 实际上会强制 x 回到下一次循环迭代的预期值。所以递减x不会有增加更多循环迭代的效果,因为会被强制重置。

    for x in range(10):
    x -= 1
    print x
    

    将产生

    -1
    0
    1
    2
    3
    4
    5
    6
    7
    8
    

    编辑:这是您尝试做的事情的一种可能性,尽管对于您的特定用例来说,接受的答案更容易。使用while 而不是for:

    limit = len(nums) - 1
    x = 0
    while x < limit:
      if nums[x] == nums[x+1]:
        nums.pop(x)
        x -= 1
      x += 1
    return nums
    

    尽管由于您访问列表元素的方式,此代码可能仍会因IndexError 而失败。但是,这就是您添加额外迭代的方式。

    【讨论】:

    • Java 实际上是我的第一语言,我很肯定这完全基于我使用 Java 的经验。只是去展示那里有多少东西要学。谢谢你的解释,男人/女人。它真的让事情变得清晰,给了我一些观点。
    • 非常感谢您的编辑。但是,在这个 while 循环中,x 不应该增加吗?
    • @user3236859 哎呀,它当然应该。
    • 再次感谢。可悲的是,我已经检查了一个答案,但我希望我可以检查多个(即使我真的不知道这些检查完成了什么)。
    • @user3236859 向上箭头表示有用的答案,而复选标记表示给定答案是解决您的特定问题的“正确”答案,或任何适当的类似物。
    【解决方案3】:

    通常,您永远不想在循环中操作计数器(除了将其设置为跳出循环)。出于类似的原因,你不想在砍树时看到你正坐在树枝上:-)

    更安全的路线(与嵌套循环相比)是在一个循环中构建一组操作,然后将此组传递给第二个循环(每个循环深一层)。

    【讨论】:

      猜你喜欢
      • 2011-10-15
      • 2014-02-03
      • 1970-01-01
      • 2020-02-10
      • 1970-01-01
      • 2017-01-26
      • 2022-12-04
      • 2017-03-22
      • 2020-01-21
      相关资源
      最近更新 更多