【问题标题】:defaultdict with a parameter to the class constructor带有类构造函数参数的 defaultdict
【发布时间】:2011-05-07 14:26:22
【问题描述】:

[Python 3.1]

我想要defaultdict(int),但我希望默认值为1 而不是0。

  1. 有什么巧妙的方法可以做到这一点吗?
  2. 我应该这样做吗?

【问题讨论】:

    标签: python collections dictionary python-3.x


    【解决方案1】:

    使用 partial 你可以创建一个带有默认参数的函数:

    from functools import partial
    from collections import defaultdict
    
    int1 = partial(int, 1)
    mydict = defaultdict(int1)
    mydict[1]
    

    而一个类的行为就像一个创建对象的函数。

    也可以使用关键字参数,例如:

    from functools import partial
    from collections import defaultdict
    
    class Rectangle:
    
       def __init__(x, y, l=10, h=20):
          self.x = x
          self.y = y
          self.l = l
          self.h = h
    
    TopSquare30 = partial(Rectangle, 0, 0, l=30, h=30)
    
    rectangles = defaultdict(TopSquare30)
    john_square = rectangles['john']
    paul_square = rectangles['paul']
    

    请注意,这里的默认参数将始终具有在执行partial 时给出的值。

    使用 lambda 或函数的其他答案将使用它们在创建对象时计算的值。

    【讨论】:

      【解决方案2】:
      defaultdict(lambda: 1)
      

      例如

      >>> from collections import defaultdict
      >>> a = defaultdict(lambda: 1)
      >>> a["foo"] += 1
      >>> a["foo"]
      2
      

      【讨论】:

        【解决方案3】:
        >>> def f():
                return 1
        >>> a = defaultdict(f)
        >>> a[1]
        1
        

        这是另一个使用 lambda 表达式的实现(来自 kindall):

        >>> a = defaultdict(lambda: 1)
        

        【讨论】:

        • 或a = defaultdict(lambda: 1)
        【解决方案4】:

        来自文档:

        总是返回零的函数 int() 只是常量函数的一个特例。创建常量函数的一种更快、更灵活的方法是使用 itertools.repeat() ,它可以提供任何常量值(不仅仅是零):

        >>> def constant_factory(value):
        ...     return itertools.repeat(value).next
        >>> d = defaultdict(constant_factory('<missing>'))
        >>> d.update(name='John', action='ran')
        >>> '%(name)s %(action)s to %(object)s' % d
        'John ran to <missing>'
        

        【讨论】:

        • 我最近碰巧在文档中读到了这一点,不敢相信他们建议使用itertools.repeat(),而@gnibbler 建议的琐碎的lambda 也可以工作,更简单,并且需要更少的开销——谈论矫枉过正......
        • 是的,我不确定。也许有性能提升,我稍后会测试它
        • 我很高兴看到没有 lambda 的替代方案。
        • def constant_factory(value):return value 也是无 lambda
        • @AndoJurai,默认字典 calls 您提供的任何参数都没有参数,因此它必须是可调用的。 int、str、list、dict 等类型都是可调用的(例如尝试int())。当然也可以使用函数,或者带有__call__方法的实例
        猜你喜欢
        • 2021-07-05
        • 1970-01-01
        • 2011-11-29
        • 1970-01-01
        • 2021-10-25
        • 2011-04-29
        • 2018-06-03
        • 2013-11-05
        • 1970-01-01
        相关资源
        最近更新 更多