Есть ли в Python «бесконечный словарь»? - PullRequest
0 голосов
/ 22 марта 2012

Есть ли что-то вроде "бесконечного словаря" в Python?

Точнее, есть что-то, где - я могу положить в значения, как в словаре, - но, возможно, также функция, которая говорит мне, как сопоставить ключ со значением, - а может также что-то, что сопоставляет ключ с (конечным) набором ключей и затем дает соответствующее значение? Сформулированная по-другому, я хочу иметь следующую «вещь»: Я инициализирую его некоторым способом (присваиваю значения, функции и т. Д.), А затем он просто дает мне для каждого ключа значение (по запросу).

Ответы [ 5 ]

4 голосов
/ 22 марта 2012

То, что вам нужно, называется «функцией».

Теперь на менее саркастической ноте: я не знаю точно, чего вы пытаетесь достичь, но вот пример:

Вам нужен фрагмент кода, который возвращает 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 голосов
/ 22 марта 2012

Вы захотите создать класс с помощью специального метода __getitem__(self,key), который возвращает соответствующее значение для этого ключа.

2 голосов
/ 22 марта 2012

Если вы хотите нормальное поведение для существующих ключей и специальное поведение для несуществующих ключей, есть метод __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}
1 голос
/ 22 марта 2012

Я думаю, вы хотите что-то вроде этого, где вы 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
1 голос
/ 22 марта 2012

Простой способ сделать это - использовать функциональный объект для обоих вариантов использования.Если вы хотите использовать функцию ключ-значение, вы просто используете ее непосредственно в качестве ссылки.Чтобы адаптировать обычный словарь к этому интерфейсу, вы можете заключить его в лямбда-блок .Вот так:

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