Is there an “infinite dictionary” in Python?

独自空忆成欢 提交于 2019-12-13 05:24:36

问题


Is there something like an "infinite dictionary" in Python?

More precisely, is there something where - i can put in values like in a dictionary, - but maybe also a function which tells me how to map a key to a value, - and maybe also something that maps a key to a (finite) set of keys and then gives the corresponding value? Formulated in another way, what I want to have is the following "thing": I initialize it in a way (give values, functions, whatever) and then it just gives me for each key a value (on request).


回答1:


What you need is called a "function".

Now, on a less sarcastic note: I don't know exactly what you are trying to achieve, but here's an example:

You want a piece of code that returns the nth element in an arithmetic progression. You can do it this way with functions:

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

This can be extended if, for example, you need a function that retains state.

Hope this helps




回答2:


You will want to create a class with the special method __getitem__(self,key) that returns the appropriate value for that key.




回答3:


If you want normal behaviour for existing keys, and special behavior for non-existing keys, there's the __missing__ method that's called for missing keys.

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)

Output:

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



回答4:


An easy way to do this would be to use a function object for both use cases. If you want to use a key-value function, you just just use it directly as a reference. To adapt an ordinary dictionary to this interface, you can wrap it in a lambda block. Like so:

# 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:


I think you want something like this, where you dict act like a normal dictionary but for special keys you want to change the behavior e.g.

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

output:

A 3 4


来源:https://stackoverflow.com/questions/9812369/is-there-an-infinite-dictionary-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!