【问题标题】:Appending python dictionaries, without replacing if the value is empty附加python字典,如果值为空则不替换
【发布时间】:2014-09-20 05:54:38
【问题描述】:
dict1 = {"Country":"",
         "State":"California"}

dict2 = {"Country":"United_states",
        "State":""}

我需要将dict2 的值添加到dict1,这样dict1 就会变成

dict1
>>>{u"Country":"United_states", 
    u"State":"California"}

如果我只是做dict1.update(dict2) 或类似的事情,它会结束

dict1
>>>{u"Country":"United_states", 
    u"State":""}

由于dict2 的“状态”中的空值覆盖了“状态”键

提前致谢

【问题讨论】:

    标签: python dictionary merge append overwrite


    【解决方案1】:

    你可以filter第二个字典,然后更新:

    dict1 = {"Country":"", "State":"California"}
    dict2 = {"Country":"United_states", "State":""}
    
    dict1.update(filter(lambda x: x[1] is not '', dict2.items()))
    
    print(dict1)
    # {'Country': 'United_states', 'State': 'California'}
    

    【讨论】:

      【解决方案2】:

      最简单的方法可能是使用过滤掉空值的dict理解:

      dict1.update({k: v for k, v in dict2.items() if v})
      

      如果你不明白它是如何工作的,你可以将 dict 理解转换成一个显式循环:

      filtered_dict2 = {}
      for k, v in dict2.items():
          if v:
              filtered_dict2[k] = v
      dict1.update(filtered_dict2)
      

      如果您发现自己经常这样做,您可能想要编写一个包装函数。例如,IIRC,Celery 有一个类似这样的辅助函数:

      def dictfilter(pred, d=None):
          """dictfilter(d) -- returns a dict with all non-empty values from d
          dictfilter(pred, d) -- returns a dict with all values from d where pred(v)"""
          if d is None:
              return {k: v for k, v in pred.items() if v}
          else:
              return {k: v for k, v in d.items() if pred(v)} 
      

      (是的,这个接口,就像任何带有可选的第一个参数和一个强制的最后一个参数的接口一样,是可怕的,但它旨在与内置的filter 兼容,它可以追溯到 Python 1 .x 并且更改为时已晚...)

      那么你可以这样做:

      dict1.update(dictfilter(dict2))
      

      【讨论】:

      • 值得注意的是,字典推导仅在 Python 2.7 中引入,因此如果您需要支持 2.6 或更早版本,请使用其中一种替代方法。
      • 好吧,对不起,也许我应该指定,我还希望空的 "" 值在两个字典中都为空的情况下仍然是空值,所以如果 dict1dict2 都有第三个key:value 例如"city":"" 然后我希望最终字典仍然有"city":""
      • @FanMa:你试过这个代码吗?这正是它的作用。在这种情况下,传递给update 的字典中不会有"city" 键,因此现有的"city": "" 将被update 单独留下。
      • @PeterGibson:是的,通常的替代方法是将genexpr 传递给dict 构造函数:dict1.update(dict((k, v) for k, v in dict2.items() if v))。但是,dict.update 自从我认为 2.4 以来,已经能够采用任何可迭代的对,因此您可以将 dict 关闭:`dict1.update((k, v) for k, v in dict2.items()如果 v)。但实际上,在新项目中使用 2.6 已经没有那么多借口了。 2.7,有时; 2.6,很少见。
      • 是的,我试过你的代码,我发现了问题。因为当您说if v: 时,您正在检查v 是否是None,这与我正在寻找的空字符串不同。基本上我只是把它改成了if v!="":,它就起作用了。不过感谢花花公子的包装器,将来肯定会使用它(修改它以适应项目需求)
      猜你喜欢
      • 2017-09-08
      • 2010-12-14
      • 2022-01-05
      • 2020-12-25
      • 2022-11-15
      • 2021-12-28
      • 2013-11-15
      • 2019-03-09
      • 1970-01-01
      相关资源
      最近更新 更多