【问题标题】:Unable to reset counters in for loop无法在 for 循环中重置计数器
【发布时间】:2019-12-05 12:55:51
【问题描述】:

我正在尝试修改整数列表,使每 2 个重复的整数乘以 2 并替换重复的整数。这是一个例子: a = [1, 1, 2, 3] = [2, 2 ,3] = [4 ,3]
还有:b = [2, 3, 3, 6 ,9] = [2 , 6 , 6, 9] = [2, 12 , 9]

我正在使用下面的代码来实现这一点。不幸的是,每次我找到匹配项时,我的索引都会跳过下一个匹配项。

user_input = [int(a) for a in input().split()]

for index, item in enumerate(user_input):
    while len(user_input)-2 >= index:
        if item == user_input[index + 1]:
            del user_input[index]
            del user_input[index]
            item += item
            user_input.insert(index,item)
        break

print(*user_input)

【问题讨论】:

  • 你保证所有的重复都是连续的吗?例如,[1,2,2,3,4] 将变为 [1,4,3,4]。下一步之后应该是什么样子?
  • 嘿托德,是的,我只需要更改连续的重复项。 [1, 4 , 3, 4] 是您示例中的最后一步
  • [8, 4, 2, 1, 1, 7] 想要什么结果?你想要[16, 7] 还是[8, 4, 2, 2, 7]
  • @Etika49 如果我错了,请纠正我,但我只是在 python IDLE 中运行了你的代码,它通过了你的测试用例
  • @RoryDaulton,我相信,[16, 7]

标签: python python-3.x for-loop iteration


【解决方案1】:

在 Python 中,您不应该在迭代容器对象时对其进行修改。如果您知道自己在做什么,则有一些例外,但您当然不应该更改容器对象的大小。这就是您正在尝试做的事情,这就是它失败的原因。

相反,请使用不同的方法。遍历列表但构造一个新列表。根据需要修改该新列表。这是执行您想要的代码的代码。这将构建一个名为 new_list 的新列表,并更改该列表中的最后一项或附加一个新项。原始列表永远不会改变。

user_input = [int(a) for a in input().split()]

new_list = []
for item in user_input:
    while new_list and (item == new_list[-1]):
        new_list.pop()
        item *= 2
    new_list.append(item)

print(*new_list)

此代码通过了您提供的两个示例。它还传递了示例[8, 4, 2, 1, 1, 7],这应该导致[16, 7]。我以前的版本没有通过最后一次测试,但是这个新版本可以。

【讨论】:

  • 谢谢你,Rory,我只是想知道为什么第一个版本没有通过所有的测试。第二版效果很好。我现在将使用调试器查看代码以了解原因:)
  • @Etika49:我的第一个版本只查看了新列表中的最后一项,而我的新版本不断回顾,直到找到与当前项不相等的列表项。
【解决方案2】:

检查这是否可行,罗里!

import copy
user_input = [1,1,2,3]
res = []
while res!=user_input:
    a = user_input.pop(0)
    if len(user_input)!=0
        b = user_input.pop(0)
        if a==b:
            user_input.insert(0,a+b)
        else:
            res.append(a)
            user_input.insert(0,b)
    else:
        res.append(a)
        user_input = copy.deepcopy(res)

【讨论】:

  • 你为什么要让 Rory 检查这个?
【解决方案3】:

您可以使用itertools.groupby 和递归:

检查相同的连续元素:

def same_consec(lst):
    return any(len(list(g)) > 1 for _, g in groupby(lst))

替换连续相同的元素:

def replace_consec(lst):
    if same_consec(lst):
        lst = [k * 2 if len(list(g)) > 1 else k for k, g in groupby(lst)]
        return replace_consec(lst)
    else:
        return lst

用法

>>> a = [8, 4, 2, 1, 1, 7] 
>>> replace_consec(a)
[16, 7]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2021-05-23
    相关资源
    最近更新 更多