【问题标题】:Can a simple counter not go negative in python?一个简单的计数器不能在 python 中变为负数吗?
【发布时间】:2025-11-22 17:50:02
【问题描述】:

我有两本词典:

members_singles = {'member3': ['PCP3'], 'member4': ['PCP1'], 'member11': ['PCP2'], 'member12': 
['PCP3'], 'member14': ['PCP4'], 'member15': ['PCP4'], 'member16': ['PCP4'], 'members17': ['PCP3']}

providers = {
"PCP1" : 3,
"PCP2" : 4,
"PCP3" : 1,
"PCP4" : 2,
"PCP5" : 4,
}

我想遍历members 并且每次出现特定值时,从providers 中的匹配计数倒数一个

to_remove_zero = []
pcps_in_negative = []
for member, provider_list in members_singles.items():
    provider = provider_list[0]
    if provider in providers:
        providers[provider] -= 1
        if providers[provider] == 0:
            to_remove_zero.append(provider)
        elif providers[provider] < 0:
            pcps_in_negative.append(provider)
        else:
            pass

我想将那些最终计数为零的提供者保存到一个列表中,并将那些负数的提供者保存到另一个列表中。但我的结果显示 to_remove_zero 包含 ['PCP3', 'PCP4'] 即使它们应该是负面的。所以循环在它们到达第二个条件之前将它们弹出。像这样的python简单计数器在倒计时时会停在零还是我错过了什么?

【问题讨论】:

  • 在第一个 sn-p 你提到“members_singles”。第二个是“members_with_one_choice”。它们有关系吗?
  • 是的,很抱歉,实际上有相同的,但我忘了在我的问题中将它们更改为相同
  • @Greg 给出了正确答案:如果提供者达到 0,它将从“提供者”中删除,并且不能进一步递减。
  • @MichaelButscher 我已经编辑了我的原始问题并删除了“pop”命令。它仍然不会低于零并做我想做的事

标签: python dictionary counter


【解决方案1】:

providers 计数达到零时,您的代码会将提供程序添加到to_remove_zero 列表中。但是计数可能稍后会变为负数,这会将相同的提供者添加到pcps_in_negative 列表中。此时,您的代码需要回溯并将其从to_remove_zero 列表中删除:

providers[provider] -= 1
if providers[provider] == 0:
    to_remove_zero.append(provider)
elif providers[provider] < 0:
    pcps_in_negative.append(provider)
    # back-track
    if provider in to_remove_zero:
        to_remove_zero.remove(provider)

如果你使用集合,这可能会更整洁:

to_remove_zero = set()
pcps_in_negative = set()
for member, provider_list in members_singles.items():
    provider = provider_list[0]
    if provider in providers:
        providers[provider] -= 1
        if providers[provider] == 0:
            to_remove_zero.add(provider)
        elif providers[provider] < 0:
            pcps_in_negative.add(provider)
            to_remove_zero.discard(provider)

【讨论】:

    【解决方案2】:

    这可能是因为您正在更改列表,同时期望索引保持一致:

    a = [1,2,3]
    a[0]
    # 1
    a.pop()
    # 3
    a[0]
    # 1
    

    【讨论】:

    • 即使我不将它们弹出并更改原始提供程序对象,当它应该为负时,它会将 PCP 和 PCP4 附加到零列表中
    • 我不是在弹出列表,而是在弹出字典。字典没有这样的索引
    • @BenSmith 在倒计时到负数期间它达到零,这会触发附加到零列表。在第一个循环之后将添加到零和次零列表移动到第二个循环中的“提供者”
    最近更新 更多