使用自定义排序功能对词典进行排序 [英] Sort a dictionary with custom sorting function

查看:133
本文介绍了使用自定义排序功能对词典进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些使用json.load(data_file)

 {
  "unused_account":{
    "logins": 0,
    "date_added": 150
  },
  "unused_account2":{
    "logins": 0,
    "date_added": 100
  },
  "power_user_2": {
    "logins": 500,
    "date_added": 400,
    "date_used": 500
  },
  "power_user": {
    "logins": 500,
    "date_added": 300,
    "date_used": 400
  },
  "regular_user": {
    "logins": 20,
    "date_added": 200,
    "date_used": 300
  }
}

我想按特定顺序对条目进行排序.我发现很多示例可以按键或单个值进行排序.但我想按以下规则对值进行排序:

I want to sort the entries in a specific order. I have found lots of examples to sort by key or one single value. But I would like to sort the values by these rules:

  1. groupby登录降序,但先登录0的用户
  2. 按日期添加的登录名对0个用户进行排序
  3. 按date_used排序至少登录1次的用户

理想情况下,我会这样编写自己的比较函数:

Ideally I would write my own compare function like this:

def compare(elem1, elem2):
    """Return >0 if elem2 is greater than elem1
        <0 if elem2 is lesser than elem1
        0 if they are equal"""
    #rule 1 group by logins
    if elem1['logins'] != elem2['logins']:
        if elem1['logins'] == 0:
            return -1
        if elem2['logins'] == 0:
            return 1
        return elem2['logins'] - elem1['logins']
    # rule 2 sort on date_added
    if elem1['logins'] == 0 and elem2['logins'] == 0:
        return elem2['date_added'] - elem1['date_added']
    #rule 3 sort on date_used
    if elem1['logins'] == elem2['logins'] and elem1['loigns'] > 0:
        return elem2['date_used'] - elem1['date_used']
    return 0  # default

我不知道在哪里以及如何插入我的排序功能.

I don't know where and how to plugin my sorting function.

推荐答案

我将假设您知道字典是无序的,并且要对值或键值对进行排序.以下示例对值进行排序.

I'm going to assume you know that dictionaries are unordered and that you want to sort either the values, or the key-value pairs. The following examples sort the values.

只要您在最后一个if中修复了loigns错字,您的比较功能就已经可以使用了:

Your comparison function already works, provided you fix the loigns typo in the last if:

>>> sorted(sample.itervalues(), cmp=compare))
[{'logins': 0, 'date_added': 150}, {'logins': 0, 'date_added': 100}, {'logins': 500, 'date_added': 400, 'date_used': 500}, {'logins': 500, 'date_added': 300, 'date_used': 400}, {'logins': 20, 'date_added': 200, 'date_used': 300}]
>>> pprint(_)
[{'date_added': 150, 'logins': 0},
 {'date_added': 100, 'logins': 0},
 {'date_added': 400, 'date_used': 500, 'logins': 500},
 {'date_added': 300, 'date_used': 400, 'logins': 500},
 {'date_added': 200, 'date_used': 300, 'logins': 20}]

但是,您也可以使用以下排序键:

However, you can use the following sort key too:

(not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])

这将创建一个(has_logins, num_logins, date)元组,其中选择的日期取决于用户是否登录.

This creates a tuple of (has_logins, num_logins, date) where the date picked is based on whether or not the user has logged in.

将其用作sorted()函数的key参数,并反转排序,如下所示:

Use it as the key argument to the sorted() function, and reverse the sort, like this:

>>> key = lambda d: (not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])
>>> pprint(sorted(sample.itervalues(), key=key, reverse=True))
[{'date_added': 150, 'logins': 0},
 {'date_added': 100, 'logins': 0},
 {'date_added': 400, 'date_used': 500, 'logins': 500},
 {'date_added': 300, 'date_used': 400, 'logins': 500},
 {'date_added': 200, 'date_used': 300, 'logins': 20}]

如果还需要键,请使用dict.iteritems()并更新键功能以接受(k, d)元组:

If you needed the keys as well, use dict.iteritems() and update the key function to accept a (k, d) tuple:

>>> key = lambda (k, d): (not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])
>>> pprint(sorted(sample.iteritems(), key=key, reverse=True))
[('unused_account', {'date_added': 150, 'logins': 0}),
 ('unused_account2', {'date_added': 100, 'logins': 0}),
 ('power_user_2', {'date_added': 400, 'date_used': 500, 'logins': 500}),
 ('power_user', {'date_added': 300, 'date_used': 400, 'logins': 500}),
 ('regular_user', {'date_added': 200, 'date_used': 300, 'logins': 20})]

这篇关于使用自定义排序功能对词典进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆