>백엔드 개발 >파이썬 튜토리얼 >Python에서 두 사전을 병합하는 방법에 대한 예시 공유

Python에서 두 사전을 병합하는 방법에 대한 예시 공유

黄舟
黄舟원래의
2017-08-09 13:16:171355검색

Dictionary는 Python 언어의 유일한 매핑 유형입니다. 다음 기사에서는 Python에서 두 개의 사전(dict)을 우아하게 병합하는 방법에 대한 관련 정보를 주로 소개합니다. 코드가 아주 자세하게 소개되어 있으니 필요하신 분들은 참고하시면 됩니다.

머리말

사전은 Python에서 가장 강력한 데이터 유형 중 하나입니다. 이 기사에서는 두 사전(dict)을 병합하는 Python의 관련 내용을 자세히 소개하고 참고 및 학습을 위해 공유합니다. . 이제 설명은 이쯤 하고, 자세한 소개를 살펴보겠습니다.

두 개의 사전을 병합하는 코드 한 줄

두 개의 사전 x와 y가 있다고 가정하고, x와 y의 값을 변경하지 않고 이를 새 사전으로 병합합니다. 예를 들어


 x = {'a': 1, 'b': 2}
 y = {'b': 3, 'c': 4}

새로운 것을 얻을 것으로 예상합니다. Z의 결과, 키가 동일하면 y가 x를 덮습니다. 예상되는 결과는


>>> z
{'a': 1, 'b': 3, 'c': 4}

입니다. PEP448에는 새로운 구문을 구현할 수 있는데, 이 구문은 python3.5에서 지원됩니다. 병합된 코드는 다음과 같습니다


z = {**x, **y}

적절한 코드 라인입니다. . 많은 사람들이 여전히 python2를 사용하고 있기 때문에 python2 및 python3.0-python3.4를 사용하는 사람들을 위해 더 우아한 방법이 있지만 두 줄의 코드가 필요합니다.


z = x.copy()
z.update(y)

위 방법에서 y는 x의 내용을 덮으므로 최종 결과는 b=3입니다.

python3.5를 사용하지 않고 한 줄로 완성하는 방법

If 아직 Python 3.5를 사용하지 않았거나 이전 버전과 호환되는 코드를 작성해야 하고 이를 단일 표현식으로 실행하려는 경우 가장 효율적인 방법은 함수에 넣는 것입니다.


def merge_two_dicts(x, y):
 """Given two dicts, merge them into a new dict as a shallow copy."""
 z = x.copy()
 z.update(y)
 return z

그런 다음 한 줄의 코드 호출을 완료합니다:


 z = merge_two_dicts(x, y)


def merge_dicts(*dict_args):
 """
 Given any number of dicts, shallow copy and merge into a new dict,
 precedence goes to key value pairs in latter dicts.
 """
 result = {}
 for dictionary in dict_args:
 result.update(dictionary)
 return result

와 같이 여러 사전을 병합하는 함수를 정의할 수도 있습니다. 그런 다음 다음과 같이 사용할 수 있습니다.


z = merge_dicts(a, b, c, d, e, f, g)

모두에서 동일한 키 이전 것을 다룰 것입니다.

덜 우아한 데모

items

어떤 사람들은 이 방법을 사용합니다:


 z = dict(x.items() + y.items())

이것은 실제로 메모리에 두 개의 목록을 생성한 다음 세 번째 목록을 생성하는 것입니다. 복사가 완료되면 새 사전을 만들고 처음 세 개의 목록을 삭제하세요. 이 메서드는 성능을 소모하며 python3의 경우 items()가 객체를 반환하기 때문에 성공적으로 실행할 수 없습니다.


>>> c = dict(a.items() + b.items())
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: &#39;dict_items&#39; and 
&#39;dict_items&#39;

명시적으로 목록 z = dict(list(x.items()) + list(y.items())) 으로 캐스팅해야 합니다. 이는 너무 낭비적인 성능입니다. . 또한 items()에서 반환된 목록을 기반으로 하는 통합 메서드는 python3에서도 실패합니다. 또한 통합 메서드는 반복되는 키 값에 불확실성을 초래하므로 우선순위 요구 사항이 있는 경우입니다. 두 개의 사전을 병합하는 경우 이 방법은 완전히 부적절합니다. z = dict(list(x.items()) + list(y.items())) ,这太浪费性能了。 另外,想以来于items()返回的list做并集的方法对于python3来说也会失败,而且,并集的方法,导致了重复的key在取值时的不确定,所以,如果你对两个dict合并有优先级的要求,这个方法就彻底不合适了。


>>> x = {&#39;a&#39;: []}
>>> y = {&#39;b&#39;: []}
>>> dict(x.items() | y.items())
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unhashable type: &#39;list&#39;

这里有一个例子,其中y应该具有优先权,但是由于任意的集合顺序,x的值被保留:


>>> x = {&#39;a&#39;: 2}
>>> y = {&#39;a&#39;: 1}
>>> dict(x.items() | y.items())
{&#39;a&#39;: 2}

构造函数

也有人会这么用


z = dict(x, **y)

这样用很好,比前面的两步的方法高效多了,但是可阅读性差,不够pythonic,如果当key不是字符串的时候,python3中还是运行失败


>>> c = dict(a, **b)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings

Guido van Rossum 大神说了:宣告dict({}, {1:3})

{k: v for d in dicts for k, v in d.items()}
다음은 y가 우선순위를 가져야 하는 예이지만 임의의 집합 순서로 인해
 dict((k, v) for d in dicts for k, v in d.items())

값이 이전 2단계 방법보다 훨씬 효율적입니다. , 그러나 가독성이 낮고 파이썬적이지 않습니다. 키가 문자열이 아닌 경우에도 python3


import itertools
z = dict(itertools.chain(x.iteritems(), y.iteritems()))

에서 실행되지 않습니다. Guido Master van Rossum이 말했습니다: dict({}, { 1:3})은 결국 메커니즘의 남용이므로 불법입니다. 이 방법은 좀 더 해킹적이지만 너무 기회주의적입니다.


성능은 좋지 않지만 더 우아한 일부 방법


다음 방법은 성능이 좋지는 않지만 항목 방법보다 훨씬 좋습니다. 그리고 우선순위를 지원합니다.

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(),y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934
python2.6에서는 다음을 수행할 수 있습니다.

>>> min(timeit.repeat(lambda: {**x, **y}))
0.4094954460160807
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.7881555100320838
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.4525277839857154
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))
2.3143140770262107
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
3.2069112799945287

itertools.chain은 키-값 쌍의 반복자를 올바른 순서로 연결합니다:


rrreee


성능 테스트

다음은 Python 2.7(시스템 Python)의 Ubuntu 14.04에서 수행되었습니다.

🎜🎜rrreee🎜in python3.5 🎜🎜🎜🎜rrreee🎜🎜🎜 요약 🎜🎜🎜

위 내용은 Python에서 두 사전을 병합하는 방법에 대한 예시 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.