【问题标题】:Sorting list of dictionaries with primary key from list of keywords and alphabetical order as secondary key以关键字列表中的主键和字母顺序作为辅助键的字典列表排序
【发布时间】:2015-10-21 06:26:04
【问题描述】:

我有一个字典列表,我希望它们根据作为主键的关键字列表进行排序,否则按字母顺序排列相等的条目。

目前我首先按字母顺序排序,然后根据提供的关键字进行排序,由于使用了稳定的排序算法,这会产生所需的结果。但是,我认为这可以一步完成,但我不知道为什么。有人可以帮忙吗?

其次,我希望能够在关键字排序部分使用关键字而不是完全匹配。我该怎么做?

到目前为止,这是我的代码:

# Define the keywords I want to see first
preferred_projects = ['project one', 'project two', 'project three']

# example data
AllMyProjectsFromaDatasource = [{ 'name': 'project two', 'id': 5, 'otherkey': 'othervalue'},
                                { 'name': 'project three', 'id': 1, 'otherkey': 'othervalue'},
                                { 'name': 'project one', 'id': 3, 'otherkey': 'othervalue'},
                                { 'name': 'abc project', 'id': 6, 'otherkey': 'othervalue'},
                                { 'name': 'one project', 'id': 9, 'otherkey': 'othervalue'}
                               ]    


def sort_by_preferred(key):
    """Sort lists out by prefered name."""
     sortkey = key['name']
     return preferred.index(sortkey) if sortkey in preferred else len(preferred)

# First sort alphabetical    
AllProjects = sorted(AllMyProjectsFromaDatasource,
                     key=lambda k: k['name'])

# Then sort by keyword
preferred = preferred_projects
AllProjects.sort(key=sort_by_preferred)

所以实际上我想像这样定义我的“排序过滤器”:

preferred_projects = ['one', 'two', 'three']

然后将列表排序如下:

[{ 'name': 'one project', 'id': 9, 'otherkey': 'othervalue'}
 { 'name': 'project one', 'id': 3, 'otherkey': 'othervalue'},
 { 'name': 'project two', 'id': 5, 'otherkey': 'othervalue'},
 { 'name': 'project three', 'id': 1, 'otherkey': 'othervalue'},
 { 'name': 'abc project', 'id': 6, 'otherkey': 'othervalue'},]    

【问题讨论】:

  • 你能举一个你的字典的例子吗?
  • 从其他解决方案中,我仍然想念我的第二个问题:我只想选择“one”,所以无论哪个项目包含在它的名称“one”中,都将是第一位的。

标签: python sorting dictionary


【解决方案1】:

您可以使用in-operator 来查明一个子字符串是否包含在另一个字符串中。

对于 Unicode 和字符串类型,当且仅当 xy 的子字符串时,x in y 为真。等效测试是y.find(x) != -1。 [...] 空字符串始终被视为任何其他字符串的子字符串,因此 "" in "abc" 将返回 True

您可以使用它来实现您的关键字排序键。

您将使用另一个答案中给出的方法(将元组作为键传递)来实现按字母排序作为辅助键。

这是一个例子:

import pprint

# Define the keywords I want to see first
preferred_projects = ['one', 'two', 'three']

# example data
AllMyProjectsFromaDatasource = [{ 'name': 'project two', 'id': 5, 'otherkey': 'othervalue'},
                                { 'name': 'project three', 'id': 1, 'otherkey': 'othervalue'},
                                { 'name': 'project one', 'id': 3, 'otherkey': 'othervalue'},
                                { 'name': 'abc project', 'id': 6, 'otherkey': 'othervalue'},
                                { 'name': 'one project', 'id': 9, 'otherkey': 'othervalue'}
                               ]    

def keyfunc(x):
    # keyword primary key
    # (add index to list comprehension when keyword is in name)
    preferred_key = [float(idx) 
                     for idx, i in enumerate(preferred_projects)
                     if i in x['name']]
    # found at least one match in preferred keywords, use first if any, else infinity
    keyword_sortkey = preferred_key[0] if preferred_key else float('inf')
    # return tuple to sort according to primary and secondary key
    return keyword_sortkey, x['name']

AllMyProjectsFromaDatasource.sort(key=keyfunc)

pprint.pprint(AllMyProjectsFromaDatasource)

输出是:

[{'id': 9, 'name': 'one project', 'otherkey': 'othervalue'},
 {'id': 3, 'name': 'project one', 'otherkey': 'othervalue'},
 {'id': 5, 'name': 'project two', 'otherkey': 'othervalue'},
 {'id': 1, 'name': 'project three', 'otherkey': 'othervalue'},
 {'id': 6, 'name': 'abc project', 'otherkey': 'othervalue'}]

【讨论】:

    【解决方案2】:

    您可以创建一个合适的元组作为您的排序键。第一部分是您的preferred_projects 的索引,默认值为最大索引。第二部分是允许按字母排序的名称:

    preferred_projects = ['project one', 'project two', 'project three']
    
    def sort_by(entry):
        name = entry['name']
    
        try:
            index = preferred_projects.index(name)
        except ValueError:
            index = len(preferred_projects)
    
        return (index, name)
    
    AllMyProjectsFromaDatasource = [
        { 'name': 'project two', 'id': 5, 'otherkey': 'othervalue'},
        { 'name': 'project three', 'id': 1, 'otherkey': 'othervalue'},
        { 'name': 'project one', 'id': 3, 'otherkey': 'othervalue'},
        { 'name': 'abc project', 'id': 6, 'otherkey': 'othervalue'},
        { 'name': 'one project', 'id': 9, 'otherkey': 'othervalue'}]    
    
    AllProjects = sorted(AllMyProjectsFromaDatasource, key=sort_by)
    
    for p in AllProjects:
        print p
    

    给你以下输出:

    {'otherkey': 'othervalue', 'name': 'project one', 'id': 3}
    {'otherkey': 'othervalue', 'name': 'project two', 'id': 5}
    {'otherkey': 'othervalue', 'name': 'project three', 'id': 1}
    {'otherkey': 'othervalue', 'name': 'abc project', 'id': 6}
    {'otherkey': 'othervalue', 'name': 'one project', 'id': 9}
    

    【讨论】:

      猜你喜欢
      • 2020-04-30
      • 1970-01-01
      • 2015-04-07
      • 2021-09-21
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多