Python中的多路频率功能?

时间:2016-06-28 18:41:13

标签: python function

这是我的功能:

def freq(*var):
    from functools import reduce
    from operator import getitem
    for c,i in enumerate(reversed(var)): 
        d={k:0 for k in set(i)} if c==0 else {k:d for k in set(i)}
    for row in zip(*var):
        *k,last_k=row
        reduce(getitem,k,d)[last_k]+=1

    return d

var参数看起来像(['a','b','b','c'],['one','two','two','two'])

我正在尝试返回一个包含频率计数的嵌套字典。因此结果d应如下所示:

{'a':{'one':1, 'two':0}, 'b':{'one':0, 'two':2}, 'c':{'one':0, 'two':1}}

但是我的函数返回了,这是错误的:

{'a': {'one': 1, 'two': 3}, 'b': {'one': 1, 'two': 3}, 'c': {'one': 1, 'two': 3}}

知道为什么吗?

3 个答案:

答案 0 :(得分:2)

问题是d dict中的所有嵌套dicts都是同一个对象。使用dict.copy()方法修复问题,因此更改行:

d={k:0 for k in set(i)} if c==0 else {k:d for k in set(i)}

d={k:0 for k in set(i)} if c==0 else {k:d.copy() for k in set(i)}

可以解决您的问题。详情请见Immutable vs Mutable typesHow do I pass a variable by reference?

祝你好运!

答案 1 :(得分:0)

您已经以某种方式将 d 的值初始化为同一个字典。我无法自信地解决这个问题,因为我没有安装Python3(腮红)。但是,我认为问题在于中间行的 k:d 值:我认为它会将相同的默认字典插入到每个值中。尝试为此次迭代中的每次传递创建 new 空字典。

答案 2 :(得分:0)

显然,内部dict引用同一个对象,所有内容都会同时更新,如final Callable<String> lambdaGetValString = () -> String.valueOf(this.val); 循环所示:

enumerate

循环的第二次迭代中使用的内部字典for c,i in enumerate(reversed(var)): d={k:0 for k in set(i)} if c==0 else {k:d for k in set(i)} # ^ 是同一个对象。您可以使用d代替d.copy()为每个密钥创建多个副本。

但为什么要在d上使用reduce时遇到麻烦。你的代码部分很难调试。

您可以在压缩项目上使用getitem对象来实现相同的目标:

Counter