Объединить два представления словаря в Python - PullRequest
0 голосов
/ 25 февраля 2019

Как мне объединить представления элементов двух диктов в python?

Мой пример использования: у меня есть два частных словаря в классе.Я хочу, чтобы API рассматривал их как единое целое и предоставлял метод items как таковой.Единственный способ, которым я знаю, - это объединить их, а затем дать представление о них, но для больших словарей это кажется дорогим.Я думаю о чем-то вроде a.items() + b.items()

Примечание: меня не волнуют ключевые столкновения.

Это то, что я хотел бы улучшить:

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return {**self._priv1, **self._priv2}.items()

Ответы [ 4 ]

0 голосов
/ 26 февраля 2019

вы можете использовать chain два комбинировать два или более видов.как указано:

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

Таким образом, нет копирования данных.

from itertools import chain

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return chain(self._priv1.items(), self._priv2.items())
0 голосов
/ 25 февраля 2019

Вы можете использовать ChainMap:

. ChainMap группирует несколько диктовок или других сопоставлений для создания единого обновляемого представления.Если карты не указаны, предоставляется один пустой словарь, так что новая цепочка всегда имеет хотя бы одно отображение.

from collections import ChainMap
context = ChainMap(_priv1, _priv2, ...)

Пример:

In [3]: _priv1 = {1: 2, 3: 4}

In [4]: _priv2 = {5: 6, 7: 8}

In [5]: from collections import ChainMap
   ...: context = ChainMap(_priv1, _priv2)

In [6]: context
Out[6]: ChainMap({1: 2, 3: 4}, {5: 6, 7: 8})

In [7]: _priv1.update({9: 10})

In [8]: context
Out[8]: ChainMap({1: 2, 3: 4, 9: 10}, {5: 6, 7: 8})

In [9]: context.get(9)
Out[9]: 10

Для вашего кодаНапример, я бы использовал:

from collections import ChainMap

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}
    _union_dict = ChainMap(_priv1, _priv2)

    @classmethod
    def items(cls):
        return cls._union_dict.items()
0 голосов
/ 25 февраля 2019

Вы можете использовать ChainMap:

from collections import ChainMap

class A:
    _priv1 = {'a': 1, 'b': 2}
    _priv2 = {'c': 1, 'd': 2}

    def items(self):
        return ChainMap(self._priv1, self._priv2)
0 голосов
/ 25 февраля 2019

Объединение представлений словарей ничего не значит, так как представление всегда отражает содержимое соответствующего словаря.

Таким образом, чтобы иметь другое представление, либо вы редактируете один из своих словарей, либо создаете новый (как вы это сделали), другого способа нет.См. this .

Но, возможно, вы хотите, чтобы itertools.chain перебирал несколько итераций.Это решение не навязчиво.Или, как сказали другие collections.ChainMap.Я бы использовал chain для итерации и ChainMap для поиска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...