【问题标题】:Python: Dictionary where key is tuple of unknown orderPython:字典,其中键是未知顺序的元组
【发布时间】:2022-12-24 21:01:45
【问题描述】:

我正在尝试找到一种创建字典的方法,以便我可以将值列表映射到适当的函数。

例如,我有一些看起来像这样的东西:

function_map = {('Put','Put','Call','Call'): FunctionOne,
                 ('Put','Call','Combo'): FunctionTwo,
                 ('Call','Put'):FunctionThree,
                 ('Put','Combo'):FunctionFour}

我正在苦苦挣扎的是如何处理可以在键的任何排列中的查找值。

例如,我可能会尝试执行 function_map[(Call, Put, Call, Put)],我希望它返回 FunctionOne。或者 function_map[(Combo, Put)] 我希望返回 FunctionFour

任何帮助表示赞赏!

【问题讨论】:

  • 要么更改原始地图,要么创建一个中间地图,例如对元组中的条目进行排序。
  • 作为一个愚蠢的替代方案,您可以初始化字典,其中键将是给定元组的所有可能排列,为每个键分配相同的函数并加入它们:dict.fromkeys(permutations(('Put', 'Put', 'Call', 'Call')), FunctionOne) | dict.fromkeys(permutations(('Put', 'Put', 'Combo')), FunctionTwo)

标签: python


【解决方案1】:

试试这个:

import itertools as it

function_map = {('Put','Put','Call','Call'): FunctionOne,
                ('Put','Call','Combo'): FunctionTwo,
                ('Call','Put'): FunctionThree,
                ('Put','Combo'): FunctionFour}

def func_map(x):
    for k, v in function_map.items():
        if x in it.permutations(k):
            return v
    return False

func_map(('Combo', 'Put'))()

(进入FunctionFour)

【讨论】:

    【解决方案2】:

    @The Thonnuanswer 内存效率高,但查找复杂度相当高。我在 this 评论中提到的简单替代方案是将每个元组的所有可能排列映射到同一函数:

    from itertools import permutations
    
    function_map = (
        dict.fromkeys(permutations(('Put', 'Put', 'Call', 'Call')), FunctionOne) |
        dict.fromkeys(permutations(('Put', 'Put', 'Combo')), FunctionTwo) |
        dict.fromkeys(permutations(('Call', 'Put')), FunctionThree) |
        dict.fromkeys(permutations(('Put','Combo')), FunctionFour)
    )
    function_map['Call', 'Put', 'Call', 'Put']()
    

    此选项需要更多时间来生成映射(比常规 dict 初始化慢大约 10 倍)但它使每次查找显著地快点(至少比使用函数查找快 10 倍,benchmark code.

    所以如果你会不断地在这个映射中搜索函数,我的答案更可取。

    【讨论】:

      【解决方案3】:

      您提供的示例的解决方案可能是这样的:

      from itertools import permutations
      
      function_map = {1: FunctionOne,
                      2: FunctionTwo,
                      3: FunctionThree,
                      4: FunctionFour}
      
      permutations_map = {1: list(permutations(('Put', 'Put', 'Call', 'Call'))),
                          2: list(permutations(('Put', 'Call', 'Combo'))),
                          3: list(permutations(('Call', 'Put'))),
                          4: list(permutations(('Put', 'Combo')))}
      
      
      def get_function(perm: tuple):
          for key, value in permutations_map.items():
              if perm in value:
                  return function_map[key]
      
      
      function_output = get_function(('Call', 'Put', 'Call', 'Put'))()
      

      其中function_outputFunctionOne 的输出。

      如果您非常频繁地运行此代码,则接受的答案是次优的,因为它会在您每次调用它时计算排列(使其变慢),而这只是一次查找。

      【讨论】:

        【解决方案4】:

        如果每个字典键的值都可以无序,则可以对每个元组进行排序,保证顺序一致。

        例子

        function_map = {
            ('Call', 'Call', 'Put', 'Put'): FunctionOne,
            ('Call', 'Combo', 'Put'): FunctionTwo,
            ('Call', 'Put'): FunctionThree,
            ('Combo', 'Put'): FunctionFour
        }
        

        为了访问字典的值,我建议你使用.get而不是通过[key]访问。它避免了在尝试访问不存在的密钥时出现意外错误。

        对于您的示例,您可以调用以下语句:

        function_map.get(tuple(sorted(('Call', 'Put', 'Call', 'Put'))))
        # output: <function __main__.FunctionOne>
        
        function_map.get(tuple(sorted(('Combo', 'Put'))))
        # output: <function __main__.FunctionFour>
        

        访问不存在的密钥时的输出

        function_map.get("not existing key")
        #output: <None>
        
        # If you need an other values while accessing not existing key
        function_map.get("not existing key", "default value")
        # output: 'default value'
        

        【讨论】:

          【解决方案5】:

          另一种替代解决方案是使用 .get()。它会解决你的问题。

          function_map.get(('Put','Combo'))
          

          如果要执行该功能,请尝试:

          function_map.get(('Put','Combo'))()
          

          【讨论】:

            猜你喜欢
            • 2011-08-13
            • 2014-03-17
            • 2014-02-07
            • 2018-12-07
            • 1970-01-01
            • 1970-01-01
            • 2018-08-05
            • 2011-08-03
            相关资源
            最近更新 更多