【问题标题】:Is there an "infinite dictionary" in Python?Python中有“无限字典”吗?
【发布时间】:2012-04-06 10:18:10
【问题描述】:

Python 中有没有类似“无限字典”的东西?

更准确地说,有什么地方 - 我可以像字典一样输入值, - 但也许还有一个函数告诉我如何将键映射到值, - 也许还有将键映射到(有限)键集然后给出相应值的东西? 换一种说法,我想要的是以下“东西”: 我以某种方式对其进行初始化(提供值、函数等),然后它只为每个键提供一个值(根据要求)。

【问题讨论】:

  • 所以如果我理解正确的话,你想给字典一个键,让它给你一个你没有插入字典的值吗? (你想让它从一个键中生成一个值吗?)
  • 您如何想象这种特定值和自动生成值的混合工作?如何决定是否使用特定值或调用哪个函数来产生值?
  • 我对你到底想要什么感到有点困惑。为什么简单的字典不能呢?你对 python 字典做过任何研究吗?!
  • 对不起,不明白。假设你有这本“无限字典”,请举例说明如何使用。
  • 你想要的是技术上(数学上)一个函数,问题是,你需要做什么你不能做(或不方便)用(编程上)一个函数。你真的需要一个对象来完成这项工作吗?

标签: python dictionary infinite


【解决方案1】:

如果您想要现有键的正常行为,以及不存在的键的特殊行为,可以使用 __missing__ 方法来处理缺失的键。

class funny_dict(dict):
    def __missing__(self, key):
        return "funny" * key

d = funny_dict()
d[1] = "asdf"
d[3] = 3.14
for i in range(5):
    print(i, d[i])

print(d)

输出:

0 
1 asdf
2 funnyfunny
3 3.14
4 funnyfunnyfunnyfunny
{1: 'asdf', 3: 3.14}

【讨论】:

    【解决方案2】:

    你需要的是一个“函数”。

    现在,不那么讽刺了:我不知道你想要达到什么目的,但这里有一个例子:

    您需要一段代码来返回算术级数中的第 n 个元素。你可以用函数来做到这一点:

    def progression(first_element, ratio):
        def nth_element(n):
            return n*ratio + first_element
        return nth_element
    
    my_progression = progression(2, 32)
    print my_progression(17) # prints 546
    

    这可以扩展,例如,如果您需要一个保留状态的函数。

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      我认为你想要这样的东西,你 dict 的行为就像一个普通的字典,但对于特殊的键你想改变行为,例如

      class InfiniteDict(dict):
          def __init__(self, *args, **kwargs):
              self.key_funcs = kwargs.pop('key_funcs', [])
              super(InfiniteDict, self).__init__(*args, **kwargs)
      
          def __getitem__(self, key):
              try:
                  return super(InfiniteDict, self).__getitem__(key)
              except KeyError:
                  return self._get_value_from_functions(key)
      
          def _get_value_from_functions(self, key):
              """
              go thru list of user defined functions and return first match
              """
              for key_func in self.key_funcs:
                  try:
                      return key_func(key)
                  except KeyError:
                      pass
      
              raise KeyError(key)
      
      def double_even_int(key):
          try:
              if int(key)%2 == 0:
                  return int(key)*2
              else:
                  raise KeyError(key)
          except ValueError:
              raise KeyError(key)
      
      def tripple_odd_int(key):
          try:
              if int(key)%2 == 1:
                  return int(key)*3
              else:
                  raise KeyError(key)
          except ValueError:
              raise KeyError(key)
      
      inf = InfiniteDict(key_funcs=[double_even_int, tripple_odd_int])
      inf['a'] = 'A'
      
      print inf['a'], inf[1], inf['2']
      

      输出:

      A 3 4
      

      【讨论】:

        【解决方案4】:

        一个简单的方法是在两个用例中都使用一个函数对象。如果您想使用键值函数,您只需直接将其用作参考即可。要使普通字典适应此接口,可以将其包装在lambda block 中。像这样:

        # Use function as dictionary
        def dict_func(key):
            return key * key
        dictionary = dict_func
        print dictionary(2) # prints 4
        
        # Use normal dictionary with the same interface
        normal_dict = {1: 1, 2: 4, 3: 9}
        dictionary = lambda(key): normal_dict[key]
        print dictionary(2) # also prints 4
        
        # Lambda functions store references to the variables they use,
        # so this works too:
        def fn_dict(normal_dict):
            return lambda(key): normal_dict[key]
        dictionary = fn_dict({1: 1, 2: 4, 3: 9})
        print dictionary(3) # prints 9
        

        【讨论】:

          【解决方案5】:

          您将希望使用特殊方法 __getitem__(self,key) 创建一个类,该方法返回该键的适当值。

          【讨论】:

            猜你喜欢
            • 2010-10-26
            • 1970-01-01
            • 1970-01-01
            • 2020-10-20
            • 1970-01-01
            • 2011-09-23
            • 1970-01-01
            • 1970-01-01
            • 2020-09-07
            相关资源
            最近更新 更多