【问题标题】:Distribute list of dictionaries by key evenly按键均匀分布字典列表
【发布时间】:2021-12-16 21:45:49
【问题描述】:

我有一个这样的字典列表:

[{'User ID': '111',
  'Full Name': 'name a',
  'Role: Name': 'role a'},
 {'User ID': '222',
  'Full Name': 'name b',
  'Role: Name': 'role a'},
 {'User ID': '232',
  'Full Name': 'name c',
  'Role: Name': 'role b'},
 {'User ID': '223',
  'Full Name': 'name d',
  'Role: Name': 'role d'},
 {'User ID': '444',
  'Full Name': 'name e',
  'Role: Name': 'role d'}]

我已使用this question 的答案在列表中均匀地对角色进行排序。但我也需要他们的“全名”。

所以基本上我需要按角色对字典进行平均排序,这可以通过链接答案实现吗?

我不想要像[a, a, a, b, c, c] 这样的字典角色,我想要像[a,b,a,c,a,c] 或类似的东西。类似于链接问题的方式。

【问题讨论】:

  • 你能提供稍微大一点的数据吗?包含不同的角色并重复。
  • 只是添加了一些,基本上有大约 180 个名称,角色数量不等,但将有大约 20 个不同的角色,我需要这些角色尽可能均匀地排序
  • 我链接的问题在排序我给它的角色列表方面做得非常好,我只是不知道如何获得名字,因为现在它只是一个列表角色

标签: python list sorting dictionary


【解决方案1】:

使用如下代码:

import pprint
import random
from functools import partial
from operator import itemgetter


data = [{'User ID': '111',
         'Full Name': 'name a',
         'Role: Name': 'role a'},
        {'User ID': '222',
         'Full Name': 'name b',
         'Role: Name': 'role a'},
        {'User ID': '232',
         'Full Name': 'name c',
         'Role: Name': 'role b'},
        {'User ID': '223',
         'Full Name': 'name d',
         'Role: Name': 'role d'},
        {'User ID': '444',
         'Full Name': 'name e',
         'Role: Name': 'role d'}]

def optimize(items, quality_function, stop=1000):
    no_improvement = 0
    best = 0
    while no_improvement < stop:
        i = random.randint(0, len(items) - 1)
        j = random.randint(0, len(items) - 1)
        copy = items[::]
        copy[i], copy[j] = copy[j], copy[i]
        q = quality_function(copy)
        if q > best:
            items, best = copy, q
            no_improvement = 0
        else:
            no_improvement += 1
    return items


def quality_maxmindist(items, key=None):
    if key is None:
        def identity(e): return e

        key = identity

    s = 0
    for k, item in { key(item) : item for item in items}.items():
        indcs = [i for i in range(len(items)) if key(items[i]) == k]
        if len(indcs) > 1:
            s += sum(1. / (indcs[i + 1] - indcs[i]) for i in range(len(indcs) - 1))
    return 1. / s


quality_fun = partial(quality_maxmindist, key=itemgetter("Role: Name"))


res = optimize(data, quality_fun)
pprint.pprint(res)

输出

[{'Full Name': 'name a', 'Role: Name': 'role a', 'User ID': '111'},
 {'Full Name': 'name d', 'Role: Name': 'role d', 'User ID': '223'},
 {'Full Name': 'name c', 'Role: Name': 'role b', 'User ID': '232'},
 {'Full Name': 'name b', 'Role: Name': 'role a', 'User ID': '222'},
 {'Full Name': 'name e', 'Role: Name': 'role d', 'User ID': '444'}]

基本上,您将key 参数添加到函数quality_maxmindist(来自here),此关键参数将用于确定项目如何相等。

在您的问题的特定情况下,您可以在"Role: Name" 上使用operator.itemgetter,这样具有相同角色的项目将被视为相等。请参阅下面的代码更改与 cmets:

def quality_maxmindist(items, key=None):
    if key is None:
        def identity(e): return e

        key = identity

    s = 0
    # notice that you need to use a dictionary for finding unique items by key
    for k, item in { key(item) : item for item in items}.items():
        indcs = [i for i in range(len(items)) if key(items[i]) == k]  # notice
        if len(indcs) > 1:
            s += sum(1. / (indcs[i + 1] - indcs[i]) for i in range(len(indcs) - 1))
    return 1. / s


quality_fun = partial(quality_maxmindist, key=itemgetter("Role: Name"))
res = optimize(data, quality_fun)

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2022-12-07
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多