2012-03-15 74 views
0

对象:字典改造和反

data = [{'key': 11, 'country': 'USA'},{'key': 21, 'country': 'Canada'},{'key': 12, 'country': 'USA'}] 

的结果应该是:

{'USA': {0: {'key':11}, 1: {'key': 12}}, 'Canada': {0: {'key':21}}} 

我开始实验:

result = {} 

for i in data: 
    k = 0 
    result[i['country']] = dict(k = dict(key=i['key'])) 

,我也得到:

{'Canada': {'k': {'key': 21}}, 'USA': {'k': {'key': 12}}} 

那么我怎么能把柜台代替k?也许有一种更优雅的方式来创建字典?

+0

为什么“加拿大”:{1:{'key':21}}'而不是'加拿大':{0:{'key':21}}? – 2012-03-15 19:34:59

+0

对不起,我犯了一个错误。固定。 – vlad 2012-03-15 19:36:46

+0

@vlad发布您的解决方案,以便其他人可以获得收益 – 2012-03-15 19:49:02

回答

3

我用现有的结果项的len()

>>> import collections 
>>> data = [{'key': 11, 'country': 'USA'},{'key': 21, 'country': 'Canada'},{'key': 12, 'country': 'USA'}] 
>>> result = collections.defaultdict(dict) 
>>> for item in data: 
...  country = item['country'] 
...  result[country][len(result[country])] = {'key': item['key']} 
... 
>>> dict(result) 
{'Canada': {0: {'key': 21}}, 'USA': {0: {'key': 11}, 1: {'key': 12}}} 

有可能是做一个更有效的方法这,但我认为这将是最可读的。

+1

'has_key'已被弃用。你应该使用'如果国家不在结果:'。另外,当你需要一个字典键的缺省值时,你应该使用'defaultdict',以便自动完成测试:'result = collections.defaultdict(dict)'。 – agf 2012-03-15 20:04:57

+0

感谢您的指点。编辑。 – zigg 2012-03-15 20:11:56

1

添加的号码,使用{键:值}语法

result = {} 

for i in data: 
    k = 0 
    result[i['country']] = dict({k : dict(key=i['key'])}) 
+0

答案应该详细.. – 2012-03-15 19:46:54

+2

这仍然没有给出所需的答案 – agf 2012-03-15 19:52:56

2

@zigg's answer更好。
这里的另一种方法:

import itertools as it, operator as op 

def dict_transform(dataset, key_name=None, group_by=None): 
    result = {} 
    sorted_dataset = sorted(data, key=op.itemgetter(group_by)) 
    for k,g in it.groupby(sorted_dataset, key=op.itemgetter(group_by)): 
     result[k] = {i:{key_name:j[key_name]} for i,j in enumerate(g)} 
    return result 

if __name__ == '__main__': 
    data = [{'key': 11, 'country': 'USA'}, 
      {'key': 21, 'country': 'Canada'}, 
      {'key': 12, 'country': 'USA'}] 
    expected_result = {'USA': {0: {'key':11}, 1: {'key': 12}}, 
        'Canada': {0: {'key':21}}} 

    result = dict_transform(data, key_name='key', group_by='country') 
    assert result == expected_result 
1
dict(k = dict(key=i['key'])) 

这通过i['key']key关键字参数到dict构造函数(这是你想要的 - 因为该字符串"key"的结果被用作键),然后将结果作为k关键字参数传递给dict构造函数(这不是您想要的) - 这就是参数传递在Python中的工作原理。事实上,你有一个名为k的本地变量是无关紧要的。

为了让这里的k值被用作键的字典,最简单的方法是使用字典的文字语法:{1:2, 3:4}是其中关键1与价值2相关的字典,关键3与值4相关联。注意,在这里我们使用表达式作为键和值 - 而不是名称 - 因此我们可以使用局部变量,并且生成的字典将使用命名值。

因此,你想要{k: {'key': i['key']}}

也许有更优雅的方式来创建字典?

您可以通过追加项目来创建列表,然后将列表转换为包含dict(enumerate(the_list))的字典。这至少可以使您不必手动进行计数,但它非常间接。