【问题标题】:Is it possible to use python dict comprehension when updating values?更新值时是否可以使用python dict理解?
【发布时间】:2023-03-29 10:04:02
【问题描述】:
counts = defaultdict(int)
for elem in sets:         #list of sets
    for _ in elem:        #each set contains elements that may be duplicates among the sets
        counts[_] += 1

有没有办法对这样的代码使用字典理解?

【问题讨论】:

  • 给出样本输入输出
  • 您能解释一下为什么要为此使用 list-comp 吗?你的帖子的标题和帖子的正文有些矛盾。 list-comp 的结果是 list - 你正在做的是想要一个 dict 似乎......
  • IndentationError - 这是你的问题吗? minimal reproducible example, How to Ask
  • 通常你不想使用列表推导来获得“副作用”——如果你想要一个列表结果就使用它们。对于其他任何事情 - 使用循环 - 而不是创建您不想要的列表的副作用。
  • 题外话,但是_作为变量名的常规用法是for a throwaway,所以这里用起来比较混乱。

标签: python list-comprehension dictionary-comprehension


【解决方案1】:

Don't use a list comprehension for side effects(即更新counts)。

相反,如果将defaultdict(int) 替换为Counter,则可以将解决方案写在一行中。 (我假设你的最终目标是让你的代码更短/更干净。)

sets = [
    {1, 2, 3},
    {1, 2},
    {3},
    {3}]
# ---
from collections import Counter
counts = Counter(x for s in sets for x in s)
print(counts)  # -> Counter({3: 3, 1: 2, 2: 2})
  • 注意:您可能更喜欢使用itertools.chain.from_iterable(sets),而不是嵌套的生成器表达式。

【讨论】:

  • 是的,目标确实是看看这是否可以在一行中完成,因为它看起来是一个相当简单的迭代过程。我在想也许海象运算符或我不熟悉的其他东西可能会在这种情况下起作用。感谢您指出 Counter 集合!
【解决方案2】:

如果你坚持使用列表推导,你可以这样做:

>>> counts = {1:4, 2:5, 3:8, 4:2, 5:9}
>>> sets = [{2,3}, {3,1}, {2}]
>>> [[counts.update({e: counts[e]+1}) for e in si] for si in sets]
[[None, None], [None, None], [None]]
>>> counts
{1: 5, 2: 7, 3: 10, 4: 2, 5: 9}

但是是的,正如其他人所建议的,您可以使用 Counter:

#1:使用 Counter 从集合中获取新计数

#2:合并新的和默认的计数器

#3:让 Counter 回到你的字典中

带样本输入:

>>> counts = {1:4, 2:5, 3:8, 4:2, 5:9}
>>> sets = [{2,3}, {3,1}, {2}]
>>> from collections import Counter
>>> cntr_new = Counter(x for s in sets for x in s)
>>> cntr_new
Counter({2: 2, 3: 2, 1: 1})
>>> cntr_orig = Counter(counts)
>>> cntr_final = cntr_orig + cntr_new

最终结果:

>>> dict(cntr_final)
{1: 5, 2: 7, 3: 10, 4: 2, 5: 9}

【讨论】:

  • 该列表[[None, None], [None, None], [None]] 毫无意义。这就是为什么我们说,don't use a list comprehension for side effects。请改用普通的 for 循环。那将是一个完全有效的答案!引用How to Answer 的话,'答案可以是“不要那样做”,但也应该包括“试试这个”。'
猜你喜欢
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 2020-07-30
  • 2021-06-08
  • 2023-03-23
  • 2016-09-13
  • 2014-05-11
相关资源
最近更新 更多