如何通过密钥对复杂字典进行排序,该密钥位于字典深处?

时间:2014-08-25 20:07:32

标签: python list sorting dictionary

我有一个有这种结构的字典:

{
  "Mark":
  {
    "surname":"Johnson",
    "tags":
    [
      {
        "name":"Salary",
        "value":"5"
      },
      {
        "name":"Car manufacturer",
        "value":"Volvo"
      }
    ]
  },
  "John":
  {
    "surname":"Doe",
    "tags":
    [
      {
        "name":"Salary",
        "value":"10"
      },
      {
        "name":"Car manufacturer",
        "value":"Daewoo"
      }
    ]
  }
}

我想通过名称为“汽车制造商”的标签值对字典进行排序,以获得类似的结果:

{
  "Volvo": 
  {
    [
     "Mark":{...},...
    ]
  },
  "Daewoo":
  {
    ["John":{...}]
  }
}

有没有办法让它尽可能优雅?我可以通过制作几个嵌套循环来做到这一点(例如下面的例子),但它看起来很难看,而且效率可能不高。

cars = {}
for person in persons:
  for tag in person['tags']:
    if tag['name'] == 'Car manufacturer'
      cars[tag['value']].append(item)

4 个答案:

答案 0 :(得分:6)

老实说,您的起始数据结构设计非常糟糕。它可能会小规模地工作,但随着你的进步和你的“字典”项目变得越来越大,你已经可以看到它快速结束了。尝试改为创建一个类,并创建结构的不同实例。例如:

class Employees():
    def __init__(self):
        self.surname = ''
        self.salary = 0
        self.car_man = []  # if in case you want to add more than one car use a list type or just use string if you plan on keeping this a single value

从这里你可以创建实例,你可以更容易地跟踪它们。您甚至可以将这些单独的实例添加到字典中,然后对它们进行排序。

EX:

 Mark = Employees()
 Mark.surname = 'Johnson'
 Mark.salary = 5
 Mark.car_man = 'Volvo'

 John = Employees()
 John.surname = "Doe"
 John.salary = 10
 John.car_man = Daewoo

根据需要为这些实例添加这些实例,然后您可以将这些实例添加到字典中,并且可以更轻松地对它们进行排序。

将它们添加到字典就像这样简单:

my_dict = {}
my_dict[#key] = # your instance

答案 1 :(得分:0)

字典理解 - 尽管我倾向于羞怯 - 如果你是那种人,可能会让你的代码更具可读性。

import pprint
pp = pprint.PrettyPrinter(indent=3)

cars = {}
for person in persons:
  for tag in persons[person]['tags']:
    if tag['name'] == 'Car manufacturer':
      if tag['value'] in cars:
          cars[tag['value']][person] = persons[person]
      else:
          cars[tag['value']] = {person:persons[person]}

pp.pprint(cars)

cars = {tag['value']:{person:persons[person]} for person in persons for tag in persons[person]['tags'] if tag['name'] == 'Car manufacturer'}
pp.pprint(cars)

我同意其他人关于数据结构的看法。更不用说你提供的代码没有按照提供的那样运行,因此我们很难准确地推断出你想要的东西。

我怀疑任何人都会提出比你更有效的答案。

答案 2 :(得分:0)

可能不是最有效的,因为它每次都需要生成dict,但是你的标签列表更好地表示为dict而不是带有" name"和"价值"。

sorted(
    d.items(),
    key=lambda x: dict(
        (kv["name"], kv["value"])
        for kv in x[1]["tags"]
    )["Car manufacturer"]
)

答案 3 :(得分:0)

根据您自己的回答:

cars = {}
for name in persons:
  for tag in persons[name]['tags']:
    if tag['name'] == 'Car manufacturer':
      cars.setdefault(tag['value'],{})[name] = persons[name]
      break

产:

{'Daewoo': {'John': {'surname': 'Doe',
                     'tags': [{'name': 'Salary', 'value': '10'},
                              {'name': 'Car manufacturer',
                               'value': 'Daewoo'}]}},
 'Volvo': {'Mark': {'surname': 'Johnson',
                    'tags': [{'name': 'Salary', 'value': '5'},
                             {'name': 'Car manufacturer', 'value': 'Volvo'}]}}

}

不是很性感,但鉴于您的数据结构可能效率很高。

相关问题