Python defaultdict - 添加另一个键?
Python defaultdict - add another key?
我在这里可能没有使用正确的词,但基本上我想在提供的第一个键旁边添加另一个键。
这是我目前拥有的:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for key, value, in type_map.items():
ret.append({
'type': key,
'tags': value,
})
return ret
输入:
[
OrderedDict([
('id', 1),
('type', 'Color'),
('writable', True),
('tag', 'Blue')
]),
OrderedDict([
('id', 2),
('type', 'Color'),
('writable', True),
('tag', 'Red')
]),
OrderedDict([
('id', 3),
('type', 'Color'),
('writable', True),
('tag', 'Green')
]),
OrderedDict([
('id', 4),
('type', 'Shape'),
('writable', False),
('tag', 'Square')
]),
OrderedDict([
('id', 5),
('type', 'Shape'),
('writable', False),
('tag', 'Circle')
])
]
期望的输出:
[
{
'type': 'Color',
'writable': True,
'tags': [
{
'tag': 'Blue',
'id': 1
},
{
'tag': 'Red',
'id': 2
},
{
'tag': 'Green',
'id': 3
}
]
},
{
'type': 'Shape',
'writable': False,
'tags': [
{
'tag': 'Square',
'id': 4
},
{
'tag': 'Circle',
'id': 5
},
]
},
]
这应该如何完成?
编辑:我明白了,抱歉我完全回避了这个。这是我的 hacky 解决方案:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type'], entry['many']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for key, value, in type_map.items():
ret.append({
'type': key[0],
'many': key[1],
'tags': value
})
return ret
基本上,让我感到困惑的是如何在第一个循环完成后访问 many
。我的解决方案是快速将 type
和 many
放在一个小列表中,然后使用 [0]
和 [1]
访问它们,它有效!
这里给个建议,注意这个解是n*lg(n),你可以解n中的问题,但是如果你的数据集不是很大就无所谓了。用它作为灵感 ;)
from collections import OrderedDict
from itertools import groupby
from operator import itemgetter
from pprint import pprint
foo = [
OrderedDict([
('id', 1),
('type', 'Color'),
('writable', True),
('tag', 'Blue')
]),
...
...
...
OrderedDict([
('id', 5),
('type', 'Shape'),
('writable', False),
('tag', 'Circle')
])
]
def transform_result(data):
key_func = itemgetter('type')
for g, items in groupby(sorted(foo, key=key_func), key=key_func):
item = {'type': g, 'tags': []}
for i in items:
item['writeable'] = i['writable']
item['tags'].append({'tag': i['tag'], 'id': i['id']})
yield item
pprint(list(transform_result(foo)))
输出
[{'tags': [{'id': 1, 'tag': 'Blue'},
{'id': 2, 'tag': 'Red'},
{'id': 3, 'tag': 'Green'}],
'type': 'Color',
'writeable': True},
{'tags': [{'id': 4, 'tag': 'Square'}, {'id': 5, 'tag': 'Circle'}],
'type': 'Shape',
'writeable': False}]
我不能说我喜欢你的数据模型,但对于你给定的输入和期望的输出,你几乎拥有它:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type'], entry['writable']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for (k_type, k_writable), value in type_map.items():
ret.append({
'type': k_type,
'writable': k_writable,
'tags': value,
})
return ret
我在这里可能没有使用正确的词,但基本上我想在提供的第一个键旁边添加另一个键。
这是我目前拥有的:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for key, value, in type_map.items():
ret.append({
'type': key,
'tags': value,
})
return ret
输入:
[
OrderedDict([
('id', 1),
('type', 'Color'),
('writable', True),
('tag', 'Blue')
]),
OrderedDict([
('id', 2),
('type', 'Color'),
('writable', True),
('tag', 'Red')
]),
OrderedDict([
('id', 3),
('type', 'Color'),
('writable', True),
('tag', 'Green')
]),
OrderedDict([
('id', 4),
('type', 'Shape'),
('writable', False),
('tag', 'Square')
]),
OrderedDict([
('id', 5),
('type', 'Shape'),
('writable', False),
('tag', 'Circle')
])
]
期望的输出:
[
{
'type': 'Color',
'writable': True,
'tags': [
{
'tag': 'Blue',
'id': 1
},
{
'tag': 'Red',
'id': 2
},
{
'tag': 'Green',
'id': 3
}
]
},
{
'type': 'Shape',
'writable': False,
'tags': [
{
'tag': 'Square',
'id': 4
},
{
'tag': 'Circle',
'id': 5
},
]
},
]
这应该如何完成?
编辑:我明白了,抱歉我完全回避了这个。这是我的 hacky 解决方案:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type'], entry['many']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for key, value, in type_map.items():
ret.append({
'type': key[0],
'many': key[1],
'tags': value
})
return ret
基本上,让我感到困惑的是如何在第一个循环完成后访问 many
。我的解决方案是快速将 type
和 many
放在一个小列表中,然后使用 [0]
和 [1]
访问它们,它有效!
这里给个建议,注意这个解是n*lg(n),你可以解n中的问题,但是如果你的数据集不是很大就无所谓了。用它作为灵感 ;)
from collections import OrderedDict
from itertools import groupby
from operator import itemgetter
from pprint import pprint
foo = [
OrderedDict([
('id', 1),
('type', 'Color'),
('writable', True),
('tag', 'Blue')
]),
...
...
...
OrderedDict([
('id', 5),
('type', 'Shape'),
('writable', False),
('tag', 'Circle')
])
]
def transform_result(data):
key_func = itemgetter('type')
for g, items in groupby(sorted(foo, key=key_func), key=key_func):
item = {'type': g, 'tags': []}
for i in items:
item['writeable'] = i['writable']
item['tags'].append({'tag': i['tag'], 'id': i['id']})
yield item
pprint(list(transform_result(foo)))
输出
[{'tags': [{'id': 1, 'tag': 'Blue'},
{'id': 2, 'tag': 'Red'},
{'id': 3, 'tag': 'Green'}],
'type': 'Color',
'writeable': True},
{'tags': [{'id': 4, 'tag': 'Square'}, {'id': 5, 'tag': 'Circle'}],
'type': 'Shape',
'writeable': False}]
我不能说我喜欢你的数据模型,但对于你给定的输入和期望的输出,你几乎拥有它:
def transform_result(self, data):
type_map = defaultdict(list)
for entry in data:
type_map[entry['type'], entry['writable']].append({
'id': entry['id'],
'tag': entry['tag'],
})
ret = []
for (k_type, k_writable), value in type_map.items():
ret.append({
'type': k_type,
'writable': k_writable,
'tags': value,
})
return ret