[英]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.