2012-03-21 2 views
0

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

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

+0

Так что, если я понимаю, это правильно, вы хотите, чтобы дать словарю ключ, и он даст вам значение, которое вы не вставить в словарь? (Вы хотите, чтобы он генерировал значение из ключа?) – Corbin

+0

Как вы представляете себе это сочетание конкретных значений и автоматически генерируемых значений для работы? Как определяется, используется ли конкретное значение или какая функция вызывается для получения значения? –

+0

Я немного смущен относительно того, что именно вы хотите .. почему бы не сделать простой словарь? Вы вообще проводили какие-либо исследования в словарях python ?! –

ответ

3

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

4

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

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

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

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 

Это может быть продлен, если, например, вам нужна функция, которая сохраняет состояние.

Надеюсь, что это помогает

1

Простой способ сделать это было бы использовать объект функции для обоих случаев использования. Если вы хотите использовать функцию key-value, вы просто просто используете ее напрямую в качестве ссылки. Чтобы адаптировать обычный словарь к этому интерфейсу, вы можете обернуть его в 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 
1

Я думаю, что вы хотите что-то вроде этого, где вы 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 
2

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