简体   繁体   English

通过在Python中使用for循环从dict获取数据

[英]Get data from dict by using for-loop in Python

My input is 我的输入是

[['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]]

Expected output: 预期产量:

{
    'key':['apple','pear'],
    'value':[
        {
            'name':'john',
            'data':[3,4]
        },
        {
            'name':'anna',
            'data':[4,3]
        },
        {
            'name':'kitty',
            'data':[6,3]
        }
    ]
}

The key is a list which conclude the first part of each item, such as 'apple' 'pear', and the value is another list. key是一个列表,该列表总结每个项目的第一部分,例如“ apple”,“ pear”,而value是另一个列表。

How should I do it? 我该怎么办?

You can achieve this with the help of collections.defaultdict : 您可以在collections.defaultdict的帮助下实现:

from collections import defaultdict
value, key = defaultdict(list), []

for x in l:
    key.append(x[0])
    for k, v in x[1].items():
        value[k].append(v)

To get the result: 要获得结果:

In [15]: {'key': key, 'value': [{'name': k, 'data': v} for k, v in value.items()]}
Out[15]: 
{'key': ['apple', 'pear'],
 'value': [
  {'data': [4, 3], 'name': 'anna'},
  {'data': [6, 3], 'name': 'kitty'},
  {'data': [3, 4], 'name': 'john'}]}

For a more efficient (?) version, subclass defaultdict to customize the default __missing__ hook to call the default_factory with missing key as a parameter (I copied this text and the implementation from the other answer of mine ). 对于更有效的(?)版本,子类defaultdict可以自定义默认的__missing__挂钩,以使用缺少键作为参数来调用default_factory (我从我的其他答案中复制了此文本和实现)。 Then you'll be able to do this in a single pass: 然后,您将可以一次完成此操作:

from collections import defaultdict

class mydefaultdict(defaultdict):
    def __missing__(self, key):
        self[key] = value = self.default_factory(key)
        return value

# pass 'name' to the dictionary
value = mydefaultdict(lambda name: {'name': name, 'data': []})
key = []

for x in l:
    key.append(x[0])
    for k, v in x[1].items():
        value[k]['data'].append(v)

The result is then 结果是

In [24]: {'key': key, 'value': value.values()}
Out[24]: 
{'key': ['apple', 'pear'],
 'value': [
  {'data': [4, 3], 'name': 'anna'},
  {'data': [6, 3], 'name': 'kitty'},
  {'data': [3, 4], 'name': 'john'}]}

In Python 3, you'll have to call list(value.values()) instead of just value.values() to get a list object. 在Python 3中,您必须调用list(value.values())而不是仅仅value.values()来获取list对象。

You can use following snippet: 您可以使用以下代码段:

input = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]]

tmp = {}
output = {'key': [], 'value': []}

for item in input:
    output['key'].append(item[0])
    for name in item[1]:
        try:
            tmp[name].append(item[1][name])
        except KeyError:
            tmp[name] = [item[1][name]]

output['value'] = [{'name': name, 'data': data} for name, data in tmp.items()]

This function can help you 此功能可以帮助您

def map_data(data):
    _tmp = {}
    _keys = []
    for _d in data:
        _keys.append(_d[0])
        for _k in _d[1].keys():
            _v  = _tmp.get(_k)
            if not _v:
                _v = {"name": _k, "data": []}

            _v["data"].append(_d[1][_k])
            _tmp[_k] = _v

    return {"key": _keys, "value": [_v for _v in _tmp.values()]}

Here is my solution: 这是我的解决方案:

import json                                                                                         

my_list = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]]

name_list = [item[1] for item in my_list]  # [{'john': 3, 'kitty': 6, 'anna': 4}, {'john': 4, 'kitty
names = name_list[0].keys()  # ['john', 'kitty', 'anna']                       
name_values = [[item[key] for item in name_list] for key in names]  # [[3, 4], [6, 3], [4, 3]]
result = {                                                                     
    'key': [item[0] for item in my_list],                                      
    'value': [                                                                 
        {'name': name, 'value': value}                                         
        for (name, value) in zip(names, name_values)                           
    ]                                                                          
}                                                                              

print(json.dumps(result, indent=4))

And the output: 并输出:

{
    "value": [
        {
            "name": "john", 
            "value": [
                3, 
                4
            ]
        }, 
        {
            "name": "kitty", 
            "value": [
                6, 
                3
            ]
        }, 
        {
            "name": "anna", 
            "value": [
                4, 
                3
            ]
        }
    ], 
    "key": [
        "apple", 
        "pear"
    ]
}

EDIT: 编辑:

emmm, just found a better way to merge the dict value. emmm,刚刚找到了合并dict值的更好方法。

If the name_dict look like this one: 如果name_dict看起来像这样:

>>> name_dict
[{'john': [3], 'kitty': [6], 'anna': [4]}, {'john': [4], 'kitty': [3], 'anna': [3]}]

the task would be easy. 任务会很容易。 What's the difference? 有什么不同? The value is a list. 该值是一个列表。

Now, we can use collections.Counter to merge two dicts! 现在,我们可以使用collections.Counter合并两个字典!

>>> Counter(name_dict[0]) + Counter(name_dict[1])
Counter({'kitty': [6, 3], 'anna': [4, 3], 'john': [3, 4]})

so here is the new solution, we convert the value to a list first:(skip the 'key', only show the 'value'): 因此这是新的解决方案,我们首先将值转换为列表:(跳过“键”,仅显示“值”):

  from collections import Counter 

  my_list = [['apple',{'john':3,'anna':4,'kitty':6}],['pear',{'john':4,'anna':3,'kitty':3}]]
  name_list = [item[1] for item in my_list]    

  for item in name_list:                                                          
      for key, value in item.items():                                             
          item[key] = [value]                                                     

  name_values = dict(Counter(name_list[0]) + Counter(name_list[1]))  # {'john': [3, 4], 'kitty': [6, 3], 'anna': [4, 3]}             

  print([{'name': name, 'value': value} for (name, value) in name_values.items()])

  # output
  [{'name': 'john', 'value': [3, 4]}, {'name': 'kitty', 'value': [6, 3]}, {'name': 'anna', 'value': [4, 3]}]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM