Существует ли цепочка для карт Python?

#python #generator

#python #генератор

Вопрос:

В Python можно лениво расширять список с помощью itertools.chain :

 L = itertools.chain(L1, L2)
  

Существует ли оператор «склеивания» отложенной карты? Т.е.,

 M = glue(M1, M2)
  

где

 M['blah']
  

ВОЗВРАТ

 M1['blah'] if 'blah' in M1 else M2['blah']
  

и, M имеет соответствующие генераторы для keys() и values() .

Комментарии:

1. Добавьте коллекции. Цепная карта в качестве ответа. Готовый класс лучше пользовательского кода.

Ответ №1:

В Python 3.3 добавлены коллекции.ChainMap, которая делает именно это.

Комментарии:

1. В названии модуля есть опечатка (должна быть коллекция s ), можете ли вы, пожалуйста, исправить это? Я не могу сделать это сам, потому что редактирование было бы слишком коротким, а у меня еще нет репутации 2000 . Спасибо!

Ответ №2:

Легко создать класс для представления отложенных вычислений по списку карт и адаптировать поведение к вашему приложению. Например:

 from UserDict import DictMixin

class Map(object, DictMixin):
    def __init__(self, *maps):
        self.maps = maps
    def __getitem__(self, key):
        for m in self.maps:
            if key in m:
                return m[key]
    def keys(self):
        return list(self.iterkeys())
    def iterkeys(self):
        return (k for m in self.maps for k in m.iterkeys())
    def values(self):
        return list(self.itervalues())
    def itervalues(self):
        return (v for m in self.maps for v in m.itervalues())

def glue(*maps):
    return Map(*maps)

M1 = {'blah': 1}
M2 = {'duh': 2}

M = glue(M1, M2)
print M['blah']
print M['duh']
print list(M.keys())
print list(M.values())
  

Вывод:

 1
2
['blah', 'duh']
[1, 2]
  

Комментарии:

1. Нужно ли там явно указывать object ? DictMixin Уже не наследуется object ?

2. По крайней мере, через Python 2.7 UserDict. DictMixin — это класс старого стиля.

3. Я не знал об этом. Спасибо.

4. Возможно, вам следует сделать глубокую копию словарей. Ваш код будет делать неожиданные вещи с M1['duh'] = 3; print M['duh']