Рубрики
Без рубрики

ChainMap – поиск нескольких словарей

Автор оригинала: Doug Hellmann.

CHICMAP CLASS управляет последовательностью словарей, и ищет их в том порядке, на котором они даны, чтобы найти значения, связанные с ключами. COMPYMAP делает хороший «контекстный» контейнер, поскольку его можно рассматривать как стек, для которого происходят изменения, поскольку стек растет, с этими изменениями снова выбросаны, когда стек сжимается.

Доступ к значениям

CHICMAP поддерживает тот же API в качестве обычного словаря для доступа к существующим значениям.

collections_chainmap_read.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}

m  collections.ChainMap(a, b)

print('Individual Values')
print('a = {}'.format(m['a']))
print('b = {}'.format(m['b']))
print('c = {}'.format(m['c']))
print()

print('Keys = {}'.format(list(m.keys())))
print('Values = {}'.format(list(m.values())))
print()

print('Items:')
for k, v in m.items():
    print('{} = {}'.format(k, v))
print()

print('"d" in m: {}'.format(('d' in m)))

Детские сопоставления ищеты в порядке их передачи в конструктор, поэтому значение, сообщенное для ключевого <код> ‘C’ поставляется из словаря .

$ python3 collections_chainmap_read.py

Individual Values
a = A
b = B
c = C

Keys = ['b', 'c', 'a']
Values = ['B', 'C', 'A']

Items:
b = B
c = C
a = A

"d" in m: False

Переупорядочение

CHICMAP хранит список отображений, над которыми он ищет в списке в своем атрибуте CAPS . Этот список сметен, поэтому можно напрямую добавлять новые сопоставления или изменить порядок элементов для управления поиском и обновлению поведения.

collections_chainmap_reorder.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}

m  collections.ChainMap(a, b)

print(m.maps)
print('c = {}\n'.format(m['c']))

# reverse the list
m.maps  list(reversed(m.maps))

print(m.maps)
print('c = {}'.format(m['c']))

Когда список сопоставлений обращается, значение, связанное с <Код> ‘C’ изменения.

$ python3 collections_chainmap_reorder.py

[{'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'}]
c = C

[{'b': 'B', 'c': 'D'}, {'a': 'A', 'c': 'C'}]
c = D

Обновление значений

CHICMAP не кэширует значения в детских сопоставлениях. Таким образом, если их содержимое модифицировано, результаты отражаются при доступе CHEADMAP COMENT .

collections_chainmap_update_behind.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}

m  collections.ChainMap(a, b)
print('Before: {}'.format(m['c']))
a['c']  'E'
print('After : {}'.format(m['c']))

Изменение значений, связанных с существующими ключами, и добавление новых элементов работает так же.

$ python3 collections_chainmap_update_behind.py

Before: C
After : E

Также возможно установить значения через CHICMAP напрямую, хотя фактически изменяется только первое отображение в цепочке.

collections_chainmap_update_directly.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}

m  collections.ChainMap(a, b)
print('Before:', m)
m['c']  'E'
print('After :', m)
print('a:', a)

Когда новое значение хранится с использованием M , <код> A сопоставлено.

$ python3 collections_chainmap_update_directly.py

Before: ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
After : ChainMap({'a': 'A', 'c': 'E'}, {'b': 'B', 'c': 'D'})
a: {'a': 'A', 'c': 'E'}

<Код> ChainMap предоставляет удобный метод для создания нового экземпляра с одним дополнительным сопоставлением в передней части списка CAPS , чтобы облегчить изменение существующих основных структур данных.

collections_chainmap_new_child.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}

m1  collections.ChainMap(a, b)
m2  m1.new_child()

print('m1 before:', m1)
print('m2 before:', m2)

m2['c']  'E'

print('m1 after:', m1)
print('m2 after:', m2)

Это поведение укладки – это то, что позволяет использовать CHICMAP экземпляров, как шаблон или контексты приложения. В частности, легко добавлять или обновлять значения в одной итерации, затем выключите изменения для следующей итерации.

$ python3 collections_chainmap_new_child.py

m1 before: ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
m2 before: ChainMap({}, {'a': 'A', 'c': 'C'}, {'b': 'B', 'c':
'D'})
m1 after: ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
m2 after: ChainMap({'c': 'E'}, {'a': 'A', 'c': 'C'}, {'b': 'B',
'c': 'D'})

Для ситуаций, когда новый контекст известен или встроен заранее, также можно пройти отображение на <код> new_child () .

collections_chainmap_new_child_explicit.py

import collections

a  {'a': 'A', 'c': 'C'}
b  {'b': 'B', 'c': 'D'}
c  {'c': 'E'}

m1  collections.ChainMap(a, b)
m2  m1.new_child(c)

print('m1["c"] = {}'.format(m1['c']))
print('m2["c"] = {}'.format(m2['c']))

Это эквивалент

m2 = collections.ChainMap(c, *m1.maps)

и производит

$ python3 collections_chainmap_new_child_explicit.py

m1["c"] = C
m2["c"] = E