如何在Python Ordered字典上使用map / reduce

时间:2017-02-27 11:24:48

标签: python lambda mapreduce

我有一个嵌套的python字典:

add_filter( 'woocommerce_order_get_items', 'filter_woocommerce_order_get_items', 10, 2 );
function filter_woocommerce_order_get_items($items, $instance){
    foreach ($items as $item_id => $item_values){

        $search = array('å','ä','ö','(', ')');
        $replace = array('a','a','o', '', '');

        $items[$item_id]['name'] = str_replace($search, $replace, $item_values['name']);
    }
    return $items;
}

我从上面的字典中创建了一个有序的字典,如下所示:

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

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

收集所有具有相同'名称'的行。 :这里'美国'和'英国'。然后应用基于' boolean'的reduce方法。柱。该功能应该是二进制的' OR' (||)。

我试图像这样应用reduce:

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

但是在选择具有相同'名称'。

的所有行时却陷入困境

所以最终的Ordered字典将如下所示:

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

4 个答案:

答案 0 :(得分:1)

让我帮你一点:

  1. 你介绍的有序词典在这里并不重要。您可以省略它并在完成逻辑后引入它
  2. 我会在第一个开头将"Yes"转换为True"No"转换为False。让生活变得轻松而不复杂
  3. 您可以不使用lambdareduce。 Python将列表理解与any语句一起使用。 any将布尔or运算符应用于布尔值列表。

答案 1 :(得分: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这是你原来的字典

答案 2 :(得分:1)

下面是一个似乎与您提供的数据一起使用的方法,但我不确定这与reduce有什么关系。

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'})])

答案 3 :(得分: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)

不需要有序字典。