【问题标题】:How to use a DefaultDict with a lambda expression to make the default changeable?如何使用带有 lambda 表达式的 DefaultDict 来使默认值可变?
【发布时间】:2015-05-20 15:54:32
【问题描述】:

DefaultDicts 是有用的对象,它能够拥有一个字典,该字典可以使用用于定义默认值的可调用函数动态创建新键。例如。使用str 将空字符串设为默认值。

>>> food = defaultdict(str)
>>> food['apple']
''

您还可以使用 lambda 将表达式设为默认值。

>>> food = defaultdict(lambda: "No food")
>>> food['apple']
'No food'

但是,您不能将任何参数传递给此 lambda 函数,这会在尝试调用它时导致错误,因为您实际上无法将参数传递给该函数。

>>> food = defaultdict(lambda x: "{} food".format(x))
>>> food['apple']

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    food['apple']
TypeError: <lambda>() takes exactly 1 argument (0 given)

即使你尝试提供参数

>>> food['apple'](12)

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    food['apple']
TypeError: <lambda>() takes exactly 1 argument (0 given)

这些 lambda 函数如何能够响应而不是死板的表达式?

【问题讨论】:

    标签: python lambda defaultdict


    【解决方案1】:

    在表达式中使用变量实际上可以在一定程度上规避这一点。

    >>> from collections import defaultdict
    >>> baseLevel = 0
    >>> food = defaultdict(lambda: baseLevel)
    >>> food['banana']
    0
    >>> baseLevel += 10
    >>> food['apple']
    10
    >>> food['banana']
    0
    

    默认的 lambda 表达式绑定到一个变量,该变量可以更改而不会影响其已创建的其他键。当它可以绑定到仅在访问不存在的键时进行评估的其他函数时,这尤其有用。

    >>> joinTime = defaultdict(lambda: time.time())
    >>> joinTime['Steven']
    1432137137.774
    >>> joinTime['Catherine']
    1432137144.704
    >>> for customer in joinTime:
        print customer, joinTime[customer]
    
    Catherine 1432137144.7
    Steven 1432137137.77
    

    【讨论】:

      【解决方案2】:

      丑陋但可能对某人有用:

      class MyDefaultDict(defaultdict):
          def __init__(self, func):
              super(self.__class__, self).__init__(self._func)
              self.func = func
      
          def _func(self):
              return self.func(self.cur_key)
              
          def __getitem__(self, key):
              self.cur_key = key
              return super().__getitem__(self.cur_key)
      

      【讨论】:

        猜你喜欢
        • 2017-04-05
        • 2019-01-20
        • 1970-01-01
        • 2016-08-06
        • 2018-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多