简体   繁体   English

Python:字典,其中键是未知顺序的元组

[英]Python: Dictionary where key is tuple of unknown order

I am trying to find a way to create a dictionary so that I can map a list of values to an appropriate function.我正在尝试找到一种创建字典的方法,以便可以将值列表映射到适当的函数。

For example, I have something that looks like:例如,我有一些看起来像:

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

What I'm struggling with is how to deal with can a lookup value that can be in any permutation of the key.我正在努力解决的是如何处理可以在任何键排列中的查找值。

For example, I might try to do function_map[(Call, Put, Call, Put)] , and I would want this to return FunctionOne .例如,我可能会尝试做function_map[(Call, Put, Call, Put)] ,我希望它返回FunctionOne Or function_map[(Combo, Put)] I would want FunctionFour returned.或者function_map[(Combo, Put)]我希望FunctionFour返回。

Any help is appreciated!任何帮助表示赞赏!

Try this:尝试这个:

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'))()

(Goes into FunctionFour) (进入功能四)

A solution to your provided example could be something like this:您提供的示例的解决方案可能是这样的:

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'))()

where function_output is the output of FunctionOne .其中function_outputFunctionOne的输出。

If you run this code very frequently, the accepted answer is suboptimal because it computes the permutations each time you call it (making it slower), while this is just a lookup.如果您非常频繁地运行此代码,则接受的答案是次优的,因为它会在您每次调用它时计算排列(使其变慢),而这只是一个查找。

@The Thonnu 's answer is memory efficient but lookup complexity is fairly high. @The Thonnu答案是内存高效,但查找复杂度相当高。 The simple alternative which I've mentioned in this comment is to map all possible permutations of every tuple to same function:我在评论中提到的简单替代方法是将每个元组的所有可能排列映射到相同的函数:

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']()

This option takes more time to generate mapping (around 10 times slower than regular dict initialization) but it makes each lookup significantly faster (at least 10 times faster than lookup with function, benchmark code ) .此选项需要更多时间来生成映射(比常规dict初始化慢约 10 倍) ,但它使每次查找显着更快(至少比使用函数查找快 10 倍, 基准代码

So if you will continuously search for function in this mapping, my answer is preferable.因此,如果您将在此映射中不断搜索功能,我的答案更可取。


You can help my country, check my profile info .你可以帮助我的国家,查看我的个人资料信息

If the value of each dictionary key can be unordered, you can sort each tuple to ensure the order is consistent.如果每个字典键的值可以是无序的,则可以对每个元组进行排序,以确保顺序一致。

Example例子

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

In order to access the values of the dictionary, I recommend you to use .get instead of accessing via [key] .为了访问字典的值,我建议您使用.get而不是通过[key]访问。 It avoids unexpected errors while trying to access not existing keys.它在尝试访问不存在的密钥时避免了意外错误。

For your examples, you may call with the following statements:对于您的示例,您可以使用以下语句调用:

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

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

The output while accessing not existing key访问不存在的密钥时的输出

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'

Another alternative solution is to use .get().另一种替代解决方案是使用 .get()。 It will solve your problem.它会解决你的问题。

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

If you want to execute the function try:如果要执行该功能,请尝试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM