2017-02-27 61 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