按计数值对字典排序

时间:2014-05-16 02:53:00

标签: python dictionary

我正在尝试按第三列对字典的输出进行排序,或者更具体地说是示例结果中显示的值的计数。对于上下文,原始答案提供在此处:https://stackoverflow.com/a/23199901/666891。我无法从https://stackoverflow.com/a/73050/666891https://stackoverflow.com/a/613218/666891得到答案,因此我在这里问。

原始输出来自:

for k in ret.keys():
    print '%s %d' % (k,ret[k])

结果是:

google com 1132
akamaiedge net 378
bing com 381
microsoft com 197

并尝试过:

x = ret.keys()
sorted(x,key=operator.itemgetter(3))
for k in x:
    print '%s %d' % (k,ret[k])

导致:

google com 1132
akamaiedge net 378
bing com 381
microsoft com 197

最后尝试过:

for k in sorted(ret.keys(),key=operator.itemgetter(3),reverse=True):
    print '%s %d' % (k,ret[k])

导致与第一个类似的输出:

microsoft com 197
akamaiedge net 378
google com 1132
bing com 381

此外,ret.keys()的值为:

['google com', 'akamaiedge net', 'bing com', 'microsoft com']
我的具体方案的

解决方案是:

for k in sorted(ret.keys(), key=lambda k:ret[k], reverse=True):
    print "{:15} - {}".format(k, ret[k])

2 个答案:

答案 0 :(得分:1)

如果您尝试根据值进行排序,那么key参数应该得到一个函数,该函数可以给出与当前键对应的值,如下所示

d = {'google com':1132,'akamaiedge net':378,'bing com':381,'microsoft com':197}
for key in sorted(d, key=d.get):
    print "{:15} - {}".format(key, d[key])

<强>输出

microsoft com   - 197
akamaiedge net  - 378
bing com        - 381
google com      - 1132

现在,每当排序算法在字典中选取一个键时,它就会调用key函数,这是字典的getter函数,它将给出与该键对应的值。因此,与密钥对应的值将用于比较。

注1:上一段代码的问题在于,您正在使用operator.itemgetter(3),它将获取密钥中索引3处的元素。您的键是字符串,因此键中的第四个字符将用于比较。这就是你问题中最后一个例子显示的原因

mic*r*osoft com 197
aka*m*aiedge net 378
goo*g*le com 1132
bin*g* com 381

按字母顺序r > m > g

注2:第二个示例的问题是,排序不会更改x,它会返回一个新列表。因此,您仍在使用未分类的x

答案 1 :(得分:1)

我坚持使用proposed by Burhan Khalid原来的collections.Counter解决方案:

import re
from collections import Counter

with open('input.txt') as f:
    c = Counter('.'.join(re.findall(r'(\w+\(\d+\))', line.split()[-1])[-2:]) for line in f)

for domain, count in c.most_common():
    print domain, count

它使用most_common()方法,它基本上使用sorted()以相反的顺序按值对字典项进行排序。无需手动完成。

仅供参考,这是most_common()源代码在python2.7上的显示方式:

def most_common(self, n=None):
    '''List the n most common elements and their counts from the most
    common to the least.  If n is None, then list all element counts.

    >>> Counter('abcdeabcdabcaba').most_common(3)
    [('a', 5), ('b', 4), ('c', 3)]

    '''
    # Emulate Bag.sortedByCount from Smalltalk
    if n is None:
        return sorted(self.iteritems(), key=_itemgetter(1), reverse=True)
    return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1))