【问题标题】:Checking for Values in a Dictionary检查字典中的值
【发布时间】:2014-12-09 12:23:10
【问题描述】:

我对如何解决这个问题有一个想法,但我需要用大量数据对其进行优化。 我非常想找到每个状态中的所有值并记录它们出现的次数。

courses = {}

def insertIntoDataStruct(state,job,count,dict):
    if not state in dict: #adds state to list with first job and count
        dict[state] = [[job,count]]
    else:
        dict[state].append([job,count])

insertIntoDataStruct("TX", 214, 1, courses)
insertIntoDataStruct("CA", 3124, 1, courses)
insertIntoDataStruct("TX", 21455, 1, courses)
insertIntoDataStruct("CA", 5124, 1, courses)
insertIntoDataStruct("CA", 5124, 1, courses)

应该输出:

{'CA': [[3124, 1], [5124, 1], [5124, 1]], 'TX': [[214, 1], [21455, 1]]}

所以如果在 CA 中值 5124 被添加两次,它应该输出:

{'CA': [[3124, 1], [5124, 2], 'TX': [[214, 1], [21455, 1]]}

如果数字已经在状态内,我可以创建一个 for 循环来检查每次附加的东西,但是当我在添加每一行时获得数千个值来检查时,它会变得很耗时。

优化它的最佳方法是什么?

【问题讨论】:

    标签: python performance list dictionary append


    【解决方案1】:

    我会将其构建为 collections.defaultdictcollections.Counter 对象。这两个字典子类将查找状态和作业O(1),这意味着您不必手动检查structstruct[state] 中的键 - 您只需添加count,就好像它已经存在一样在那里。

    >>> from collections import Counter, defaultdict
    >>> def insert_into_data_struct(state, job, count, struct):
        struct[state][job] += count
    
    
    >>> courses = defaultdict(Counter)
    >>> insert_into_data_struct("TX", 214, 1, courses)
    >>> insert_into_data_struct("CA", 3124, 1, courses)
    >>> insert_into_data_struct("TX", 21455, 1, courses)
    >>> insert_into_data_struct("CA", 5124, 1, courses)
    >>> insert_into_data_struct("CA", 5124, 1, courses)
    >>> courses
    defaultdict(<class 'collections.Counter'>, {'CA': Counter({5124: 2, 3124: 1}), 
                                                'TX': Counter({214: 1, 21455: 1})})
    

    请注意,我已将函数重命名为符合PEP-0008


    要获取每个州的顶级课程,请使用Counter.most_common

    >>> {state: count.most_common(3) for state, count in courses.items()}
    {'CA': [(5124, 2), (3124, 1)], 'TX': [(214, 1), (21455, 1)]}
    

    用原版词典做同样的事情 (courses = {}):

    def insert_into_data_struct(state, job, count, struct):
        if state not in struct:
            struct[state] = {job: count}
        elif job not in struct[state]:
            struct[state][job] = count
        else:
            struct[state][job] += count
    

    不过,您现在必须自己找到前三名!

    【讨论】:

    • 我怎样才能使用这种方法只打印每个州最高的收藏?
    • Counter 有一个 most_common(n) 方法,所以你可以得到例如每个州的前三名是{state: count.most_common(3) for state, count in courses.items()}
    • 感谢@johnrsharpe 到目前为止我已经完成了这个计数 = Counter(courses) 打印计数,但是当我尝试打印并冻结我的应用程序时它被锁定
    • 为什么要创建Countercourses?那时courses 已经是defaultdict 了吗?
    • 所以我刚刚发现我必须在运行我的代码的 shell 上运行 2.4 所以 counter 和 defaultdict 将不起作用,回到寻找替代解决方案:(
    猜你喜欢
    • 1970-01-01
    • 2014-11-01
    • 2013-09-05
    • 1970-01-01
    • 2014-09-16
    • 2015-08-13
    • 1970-01-01
    • 2016-11-14
    相关资源
    最近更新 更多