【问题标题】:reduce functions on a dictionary python减少字典python上的函数
【发布时间】:2020-04-03 12:03:48
【问题描述】:

这可能是一个微不足道的问题,但我有一本字典,我想在字典上应用大约 10 个函数来修改其内容。

我认为这对reduce 来说是一个很好的案例,但我似乎无法让它发挥作用。

这是一个例子

from datetime import datetime
import re
from functools import reduce 


d_ = {
      "dob_partial": "20120314", 
      "service_address_country":"Uni44ed Kind-om"
     }

我想要的结果:

d_ = {
      "dob_partial": "20120314",
      "dob": datetime.datetime(2012, 3, 14, 0, 0)
      "service_address_country":"Uni44ed Kind-om"
      "service_address_country_clean":"Unied Kindom"
     }

这是可复制的代码:

# pre-processing functions

def clean_address_country_code(d):

    key = 'service_address_country'
    d[key + 'clean'] = re.sub('[^a-zA-Z ]+', '', d[key])

    return d

def add_datestr_to_date(d):

    key = 'dob_partial'
    d['dob'] = datetime.strptime(d.get(key), '%Y%m%d')

    return d

# pipeline function to apply all preprocessing functions

def apply_all_preprocessing(fns, dic):

    reduce(lambda fn, d=dic: fn(dic), fns)

    return dic

fns = [add_datestr_to_date, clean_address_country_code]

apply_all_preprocessing(fns, d_)

仅部分起作用(它仅应用列表中的第一个函数fns):

>>> print(apply_all_preprocessing(fns, d_))

{'dob_partial': '20120314', 'service_address_country': 'Uni44ed K-?indom', 'dob': datetime.datetime(2012, 3, 14, 0, 0)}

【问题讨论】:

  • 您是否在代码中的某处创建了一个名为 map 的变量?也许尝试打印地图的类型及其值
  • 谢谢克里斯,我现在就试试。
  • 以防万一你错过了:map 返回一个列表/可迭代。 reduce 期待一个可调用的。错误是什么让你感到惊讶?根据您的调试环境,只需输出 map() 以便您查看它在做什么。

标签: python dictionary functional-programming reduce functools


【解决方案1】:

交换 lambda 参数的顺序。应该是lambda value, element: ...。在你的情况下:

def apply_all_preprocessing(fns, dic):
    return reduce(lambda d,f: f(d), fns, dic)

提供初始字典作为reduce() 的最后一个参数。

【讨论】:

  • 哦 - 它奏效了。当说“它应该是 lambda value, element... 元素是我们要减少的迭代的元素?
  • 是的。 fns 中的每个元素都将放入fdic 第一次会被放入d,然后答案f(d) 将在下一次迭代中反馈给d
  • 如果你有时间---有一件事我显然没有理解,因为直觉上我会说为什么我在定义时给 lambda 参数的顺序很重要?我认为我最初直观地做的是使用lambda f, d: f(d), fns...,因为我认为定义时的顺序反映了传递参数的顺序。不确定我是否理解它为什么会破裂。
  • 参数的顺序由reduce() 调用 lambda 的方式决定。最好阅读文档:docs.python.org/3/library/functools.html#functools.reduce
  • 我希望你能更好地理解那里。它实际上让您了解reduce() 是如何实现的。这与for 循环真的没有什么不同。
【解决方案2】:

我将简化您的示例以尝试回答我认为您要问的问题。

d_ = {"A": -1, "B": 2}

def f1(n):
    return n*2

def f2(n):
    return n**2

...

所以我们有一个字典d_ 和一堆函数(fi),我们想将它们应用于它的值;也许所有这些都是按顺序排列的,也许只是其中一些以任何顺序排列。好吧,这个怎么样:

def apply_all_preprocessing(fns, dic):
    for f in fns:
      dic = {k: f(v) for k, v in dic.items()}
    return dic

fns = [f1, f2]

res = apply_all_preprocessing(fns, d_)

print(res)   # -> {'A': 4, 'B': 16}
#                       |        |= f2(f1(2)) = f2(2 * 2) = 4^2 = 16
#                       |= f2(f1(-1)) = f2(-1 * 2) = (-2)^2 = 4

【讨论】:

  • 谢谢!这将我推向了一个好的方向——我没想过使用听写理解!但是,我不想修改原始数据,我试图用修改后的数据添加一个 k:v 对(我不想覆盖任何 k:v)对。
  • @TytireRecubans 是的,我上面的例子有点抽象,但你明白了。很高兴能提供帮助。
  • 这真是太好了!谢谢-我正在使用您的逻辑解决方案:)
猜你喜欢
  • 2020-05-07
  • 2021-03-03
  • 2014-05-16
  • 2018-12-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
相关资源
最近更新 更多