[python] 파이썬에서 사전을 어떻게 병합합니까?

d3 = dict(d1, **d2)

나는 이것이 사전을 병합한다는 것을 이해합니다. 그러나 그것은 독특합니까? d1에 d2와 동일한 키가 있지만 값이 다른 경우 어떻게됩니까? d1과 d2를 병합하고 싶지만 중복 키가 있으면 d1이 우선합니다.



답변

.update()원본이 d2더 이상 필요하지 않은 경우 방법을 사용할 수 있습니다 .

다른 키 / 값 쌍으로 사전을 업데이트하고 기존 키를 덮어 씁니다 . 반환 None.

예 :

>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'b': 1, 'c': 3}
>>> d2.update(d1)
>>> d2
{'a': 1, 'c': 3, 'b': 2}

최신 정보:

물론 병합 된 새 사전을 만들기 위해 먼저 사전을 복사 할 수 있습니다. 이것은 필요하거나 필요하지 않을 수 있습니다. 사전에 복합 객체 (목록 또는 클래스 인스턴스와 같은 다른 객체를 포함하는 객체)가있는 copy.deepcopy경우에도 고려되어야합니다.


답변

Python2에서는

d1={'a':1,'b':2}
d2={'a':10,'c':3}

d1은 d2를 재정의합니다.

dict(d2,**d1)
# {'a': 1, 'c': 3, 'b': 2}

d2는 d1을 재정의합니다.

dict(d1,**d2)
# {'a': 10, 'c': 3, 'b': 2}

이 동작은 단순히 구현의 우연이 아닙니다. 문서에서 보장 됩니다 .

키가 위치 인수와 키워드 인수 모두에 지정되면 키워드와 연관된 값이 사전에 유지됩니다.


답변

d1충돌에 우선 순위 를 두려면 다음 을 수행하십시오.

d3 = d2.copy()
d3.update(d1)

그렇지 않으면 반전 d2d1.


답변

내 해결책은 병합 기능 을 정의하는 것입니다. 정교하지 않고 한 줄만 들었습니다. 다음은 Python 3의 코드입니다.

from functools import reduce
from operator import or_

def merge(*dicts):
    return { k: reduce(lambda d, x: x.get(k, d), dicts, None) for k in reduce(or_, map(lambda x: x.keys(), dicts), set()) }

테스트

>>> d = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> d_letters = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d, d_letters)
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d_letters, d)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> merge(d_letters)
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge()
{}

임의의 수의 사전 인수에 대해 작동합니다. 해당 사전에 중복 키가 있으면 인수 목록에서 가장 오른쪽 사전의 키가 우선합니다.


답변

Trey Hunner는 (python3.3 +의 경우) ChainMap사전 압축 풀기를 포함하여 여러 사전을 병합하는 여러 옵션을 설명 하는 멋진 블로그 게시물가지고 있습니다 .


답변

에서 시작 Python 3.9하여 연산자 |는 두 사전에서 병합 된 키와 값으로 새 사전을 만듭니다.

# d1 = { 'a': 1, 'b': 2 }
# d2 = { 'b': 1, 'c': 3 }
d3 = d2 | d1
# d3: {'b': 2, 'c': 3, 'a': 1}

이:

병합 된 키와 d2 및 d1 값을 사용하여 새 사전 d3을 만듭니다. d2와 d1이 키를 공유 할 때 d1의 값이 우선합니다.


또한 |=d1 값에 우선 순위를두고 d1 in을 병합하여 d2를 수정 하는 연산자에 유의하십시오 .

# d1 = { 'a': 1, 'b': 2 }
# d2 = { 'b': 1, 'c': 3 }
d2 |= d1
# d2: {'b': 2, 'c': 3, 'a': 1}


답변

위에서 언급했듯이 사용하는 d2.update(d1)것이 가장 좋은 방법이며 d2필요한 경우 먼저 복사 할 수도 있습니다.

그러나 dict(d1, **d2)키워드 인수가 문자열이어야하므로 일반적으로 사전을 병합 하는 것이 실제로는 나쁜 방법 이라는 점을 지적하고 싶습니다 . 따라서 다음 dict과 같은 경우 실패합니다 .

{
  1: 'foo',
  2: 'bar'
}