2017-02-27 33 views
0

我有一个嵌套的Python字典是这样的:如何使用地图上的Python /降低有序字典

my_dictionary = {"Ab" : {'name': 'usa', 'boolean': 'YES'}, 
"Ac" : {'name': 'usa', 'boolean': 'NO'}, 
"Ad": {'name': 'UK', 'boolean': 'NO'}, 
"Ae": {'name': 'UK', 'boolean': 'NO'}} 

我创建了一个有序字典从上面的解释是这样的:

from collections import OrderedDict 
sorted_dict = OrderedDict(sorted(my_dictionary.iteritems(), key=lambda x: x[1]['name'])) 
print sorted_dict 

这使:

OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}), 
("Ac", {'name': 'usa', 'boolean': 'NO'}), 
("Ad", {'name': 'UK', 'boolean': 'NO'}), 
("Ae", {'name': 'UK', 'boolean': 'NO'})]) 

我需要添加一个新的列('结果')到有序的字典。创建新列的逻辑如下:

收集所有具有相同“名称”的行:这里是'usa'和'UK'。然后应用基于'布尔'列的reduce方法。该函数应该是二进制“OR”(||)。

我试图申请减少这样的:

reduce(lambda x,y: x['boolean'] or y['boolean'] 

,但陷入了与同一“名称”中选择所有行。

所以最终的有序字典的样子:

OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES', 'result': 'YES'}), 
("Ac", {'name': 'usa', 'boolean': 'NO', 'result': 'YES'}), 
("Ad", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'}), 
("Ae", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'})]) 
+0

如何使用熊猫包中的数据框? – Elmex80s

+0

@ Elmex80s:我也在考虑这个问题。但是,它可以集成到一个纯Python代码库中。我只在笔记本上使用了熊猫,而不是完全成熟的项目 – user3683555

+2

不要使用'sorted'作为变量名,它会隐藏内置'sorted'方法,并且可能会给您带来问题。 –

回答

1

继承人,这似乎与你所提供的数据进行工作的方法,但我不知道如何与减少有关。

from collections import OrderedDict, defaultdict 

d = OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}), 
       ("Ac", {'name': 'usa', 'boolean': 'NO'}), 
       ("Ad", {'name': 'UK', 'boolean': 'NO'}), 
       ("Ae", {'name': 'UK', 'boolean': 'NO'})]) 


def add_result(d, ikey='name', check='boolean', tt='YES', ff='NO'): 
    # hold results per ikey 
    ikey_results = defaultdict(lambda: ff) 
    # first pass to get results 
    for v in d.values(): 
     if v[check] == tt: 
      ikey_results[v[ikey]] = tt 
    # second pass to embedd results 
    for v in d.values(): 
     v['result'] = ikey_results[v[ikey]] 
    return d 

print add_result(d) 

息率

OrderedDict([('Ab', {'boolean': 'YES', 'name': 'usa', 'result': 'YES'}), 
      ('Ac', {'boolean': 'NO', 'name': 'usa', 'result': 'YES'}), 
      ('Ad', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'}), 
      ('Ae', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'})]) 
+0

这个答案绝对正确。检查其他人 – user3683555

1

让我帮你一点点:

  1. 你介绍的有序字典没有多大意义在这里。您可以省略它并在完成逻辑后将其引入
  2. 我会在第一次开始时将"Yes"变换为True"No"False。让生活轻松,不复杂
  3. 你可以不用lambdareduce。 Python拥有列表理解和any声明。 any将布尔运算符or应用于布尔值列表。
+0

我喜欢你的第二点。对于第一点:我有10000这样的列。这是最简单的版本。我想,一旦我排序它,我应该能够在“名称”列中获取具有相同值的行。 – user3683555

+0

@ user3683555谢谢你,但第一点和第三点也可能是有价值的。 – Elmex80s

1

我不确定自己能否顺利完成。但我希望这是你正在寻找的。

from functools import reduce 
from itertools import groupby 


def reduceByKey(func, iterable): 
    return map(    
     lambda l: (l[0], reduce(func, map(lambda p: p[1], l[1]))), 
     groupby(sorted(iterable, key=lambda p: p[0]), lambda p: p[0]) 
    ) 

reduceByKey(
    # Are you sure you want to do ("YES" or "NO") not (True or False) ? 
    lambda x, y: x or y 
    map(lambda d: yourDict[d]["name"], yourDict[d]["boolean"], yourDict) 
) 

yourDict这里是你原来的字典

1

from pprint import pprint 

my_dictionary = {"Ab": {'name': 'usa', 'boolean': True}, 
       "Ac": {'name': 'usa', 'boolean': False}, 
       "Ad": {'name': 'UK', 'boolean': False}, 
       "Ae": {'name': 'UK', 'boolean': False}} 

sub_result = dict() 

for x in my_dictionary.values(): 
    country_name = x['name'] 
    sub_result[country_name ] = sub_result.get(country_name , False) or x['boolean'] 


new_dictionary = {k: dict(v.items() + [('result', sub_result[v['name']])]) for k, v in my_dictionary.items()} 


pprint(new_dictionary) 

不需要有序字典。

+0

是的,但是你正在销毁旧的物体,并创建一个新的物体。该OP所需的就地恕我直言。 –

+0

@InbarRose在这种情况下,请删除字典理解并将其替换为for循环。 – Elmex80s

+0

@ Elmex80s:这个解决方案也是对的。 – user3683555