【问题标题】:How to add or increment single item of the Python Counter class如何添加或增加 Python Counter 类的单个项目
【发布时间】:2015-07-12 04:04:33
【问题描述】:

set 使用 .update 添加多个项目,.add 添加单个项目。

为什么collections.Counter 的工作方式不同?

要使用 Counter.update 增加单个 Counter 项目,您似乎必须将其添加到列表中:

from collections import Counter

c = Counter()
for item in something:
    for property in properties_of_interest:
        if item.has_some_property: # simplified: more complex logic here
            c.update([item.property])
        elif item.has_some_other_property:
            c.update([item.other_property])
        # elif... etc

我可以让Counterset 一样行事(即无需将属性放在列表中)吗?

用例:Counter 非常好,因为它具有类似于defaultdict 的行为,即在稍后检查时为丢失的键提供默认零:

>>> c = Counter()
>>> c['i']
0

我发现自己经常这样做,因为我正在研究各种has_some_property 检查的逻辑(尤其是在笔记本中)。由于那样的混乱,列表理解并不总是可取的等等。

【问题讨论】:

  • 那么你的代码和Counter.update有什么问题?
  • 我必须把它贴在假名单上。没什么大不了的;我只是想知道没有add 背后是否有想法。
  • update 方法接受一个可迭代的 aas 参数,并且该可迭代对象应该是一个元素序列,而不是一个(键、值)对序列。
  • 就像我在评论中所说的那样 - add 甚至如何帮助你 - 你正在选择要添加的 what... 我没看到重点 - 你能举例说明.add 的工作原理吗?
  • has_some_property 与仅仅获取属性本身有不同的逻辑吗? - 另请注意 - 使用当前的 helper,您可能会将 None 结果放入您的 Counter - 这可能是可取的,也可能不是......

标签: python counter


【解决方案1】:

嗯,你真的不需要使用Counter 的方法来计数,是吗?有一个 += 运算符,它也可以与 Counter 一起使用。

c = Counter()
for item in something:
    if item.has_some_property:
        c[item.property] += 1
    elif item.has_some_other_property:
        c[item.other_property] += 1
    elif item.has_some.third_property:
        c[item.third_property] += 1

【讨论】:

  • 起初对我来说并不明显的是,即使您要递增的键在计数器中尚不存在,它也能正常工作。
【解决方案2】:
>>> c = collections.Counter(a=23, b=-9)

你可以像这样添加一个新元素并设置它的值:

>>> c['d'] = 8
>>> c
Counter({'a': 23, 'd': 8, 'b': -9})

增量:

>>> c['d'] += 1
>>> c
Counter({'a': 23, 'd': 9, 'b': -9} 

请注意,c['b'] = 0 不会删除:

>>> c['b'] = 0
>>> c
Counter({'a': 23, 'd': 9, 'b': 0})

删除使用del:

>>> del c['b']
>>> c
Counter({'a': 23, 'd': 9})

Counter 是一个 dict 子类

【讨论】:

    【解决方案3】:

    有一种更 Pythonic 的方式来做你想做的事:

    c = Counter(item.property for item in something if item.has_some_property)
    

    它使用generator expression 而不是对循环进行开放编码。

    编辑:错过了您的无列表理解段落。我仍然认为这是在实践中实际使用Counter 的方式。如果您有太多代码要放入生成器表达式或列表推导式中,通常最好将其分解为函数并从推导式中调用。

    【讨论】:

    • 一个列表推导式,一个生成器表达式——可以做到,但是对于复杂的 if/elif/elif/etc,它就不起作用了。
    • @bahmait 以及您认为set.add 如何帮助处理复杂的if/elif/elif 等...?
    • @bahmait:刚刚编辑。我猜,将逻辑分解到一个单独的函数中是 Pythonic 的方法。我同意 add() 方法可能是一个不错的补充,但也许省略是故意将人们推向生成器样式。
    • @JonClements 除了更新计数器之外,如果在每次通过时做一堆事情,难道不是让事情变得容易阅读吗?我一直在寻找 += 1 以解决慢速问题,并且将所有逻辑放在一个地方很好。这有意义吗?
    • @bahmait 是的...您接受的答案绝对是最具可读性和可扩展性的 :)
    猜你喜欢
    • 2011-02-07
    • 2017-08-27
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 2018-08-15
    • 1970-01-01
    • 2021-07-08
    相关资源
    最近更新 更多