【问题标题】:Trying to add to dictionary values by counting occurrences in a list of lists (Python)尝试通过计算列表列表中的出现次数来添加字典值(Python)
【发布时间】:2012-10-05 17:04:32
【问题描述】:

我正在尝试获取列表列表中的项目计数并将这些计数添加到 Python 中的字典中。我已经成功地制作了列表(它是单个广告查看记录的所有可能出现组合的列表)和一个字典,其键等于可能出现的所有值,现在我需要计算每个出现和更改的次数字典中的值到列表列表中对应键的计数。这是我所拥有的:

import itertools
stuff=(1,2,3,4)
n=1
combs=list()
while n<=len(stuff):
    combs.append(list(itertools.combinations(stuff,n)))
    n = n+1
viewers=((1,3,4),(1,2,4),(1,4),(1,2),(1,4)) 
recs=list()
h=1
while h<=len(viewers):
    j=1
    while j<=len(viewers[h-1]):
       recs.append(list(itertools.combinations(viewers[h-1],j))) 
       j=j+1
    h=h+1
showcount={}
for list in combs:
    for item in list:
        showcount[item]=0    
for k, v in showcount:
        for item in recs:
            for item in item:
                if item == k:
                    v = v+1

我尝试了很多不同的方法来做到这一点,但我通常要么得到“太多的值无法解包”错误,要么根本不填充。发布了几个类似的问题,但我对 Python 还很陌生,而且没有一个真正解决了我需要足够接近的问题来弄清楚它。非常感谢。

【问题讨论】:

  • 如果您能展示一些示例输入和所需的输出,那将非常方便
  • 您可能需要考虑使用Counter
  • list 不是变量名的好选择:您正在破坏内置函数 list()。你也应该仔细检查你的缩进

标签: python list dictionary count iteration


【解决方案1】:

首先,使用生成器表达式“展平”列表:(item for sublist in combs for item in sublist)

然后,遍历展平列表。对于每个项目,您可以向 dict 添加一个条目(如果它不存在),或者向值添加一个。

d = {}
for key in (item for sublist in combs for item in sublist):
    try:
        d[key] += 1
    except KeyError:  # I'm not certain that KeyError is the right one, you might get TypeError. You should check this
        d[key] = 1

此技术假定子列表的所有元素都是可散列的并且可以用作键。

【讨论】:

  • A defaultdict 已经非常简单(d = defaultdict(int)),因为它不需要try/except;但是Counter 更简单,因为您甚至不必自己计算。
  • @MartijnPieters 你是对的,你的答案是更好的答案。我只是想表明它可以只使用内置函数来完成。
  • 不要忽略标准库!正是 Counterdefaultdict 这样的东西让 Python 如此闪耀!
  • 可以保留内置函数,但仍然避免使用 try/except: d[key] = d.get(key,0) + 1
  • @reedstrm:是的,或者通过测试key in d 构造。然而,这通常比try 语句慢。
【解决方案2】:

我有一些类似问题的旧代码,它可能对面临类似问题的人有用。

import sys
file = open(sys.argv[-1], "r").read()
wordictionary={}
for word in file.split():
    if word not in wordictionary:
        wordictionary[word] = 1
    else:
        wordictionary[word] += 1
sortable = [(wordictionary[key], key) for key in wordictionary]
sortable.sort()
sortable.reverse()
for member in sortable: print (member)

【讨论】:

    【解决方案3】:

    如果您只想展平列表列表,您可以使用 itertools.chain()

    >>> import itertools
    >>> listOfLists = ((1,3,4),(1,2,4),(1,4),(1,2),(1,4)) 
    >>> flatList = itertools.chain.from_iterable(listOfLists)
    

    集合模块中的 Counter 对象可能会完成您想要的其余部分。

    >>> from collections import Counter
    >>> Counter(flatList)
    Counter({1: 5, 4: 4, 2: 2, 3: 1})
    

    【讨论】:

    • itertools.chain(*listOfLists) 更高效/Python 写成itertools.chain.from_iterable(listOfLists)
    【解决方案4】:

    使用 Counter 而不是普通的 dict 来计数:

    from collections import Counter
    
    showcount = Counter()
    for item in recs:
        showcount.update(item)
    

    甚至:

    from collections import Counter
    from itertools import chain
    
    showcount = Counter(chain.from_iterable(recs))
    

    如您所见,这让您的代码大大更简单。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 1970-01-01
      • 2022-11-23
      • 2016-09-23
      • 2013-01-21
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      相关资源
      最近更新 更多