사전을위한 파이썬“확장”


462

사전을 다른 사전으로 확장하는 가장 좋은 방법은 무엇입니까? 예를 들어 :

>>> a = { "a" : 1, "b" : 2 }
>>> b = { "c" : 3, "d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}

이 회피 for루프 를 얻기 위해 어떤 작업을 찾고 있습니다 .

{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }

나는 다음과 같은 것을하고 싶다 :

a.extend(b)  # This does not work

25
나는 목록 []을 알고 있었고, 나는 다른 사람들을 위해 일할 수 있다고 생각한다. ;-)
FerranB

답변:


694

6
문서를 읽은 후에 왜 "업데이트"가 있지만 "확장자"가 없는지 이해할 것입니다.
georg

58
update ()는 dict를 직접 수정하고 None을 반환합니다.
e18r

5
그러나 이미 정의 되지 않은 값으로 만 (예 : 기존 값을 덮어 쓰지 않고) dict를 확장하려면 어떻게해야합니까? 예를 들어 dict {"a":2, "b":3}를 dict {"b":4, "c":5}로 업데이트 하여 dict {"a":2, "b":3,"c":5}? 물론 update()물건을 움직여서 사용 하는 것이 가능 하지만 한 줄로만 달성 할 수 있다면 더 좋을 것입니다.
Nearoo

17
@Nearoo-단순히 반대 방향으로 업데이트하십시오. x.update (y) [y로 x 값을 덮어 쓰기] 대신 y.update (x) [y 값을 x로 덮어 쓰기]를 사용하고 y를 추가 작업을 위해 선택한 dict로 사용
jonathanl

update기존 항목 을 자동으로 덮어 씁니다. 즉, 겹치는 키 ba대한 값을 덮어 씁니다 .
CGFoX

186

이 닫힌 질문 에서 아름다운 보석 :

입력 dicts를 변경하지 않는 "oneliner way"는

basket = dict(basket_one, **basket_two)

무엇을 알아보기 **basket_two((가) **) 여기에 의미합니다 .

충돌하는 경우의 항목 basket_two이 의 항목을 재정의합니다 basket_one. 한 줄짜리가 가면, 이것은 읽기 쉽고 투명하며, 다른 두 가지가 섞인 받아쓰기가 도움이 될 때마다 그것을 사용하는 것에 대한 징계가 없습니다 (이해하기 어려운 독자는 실제로 이것이 그 또는 그녀가 배우고 dict**형태 를 배우도록 자극하는 방식 ;-). 예를 들어 다음과 같이 사용합니다.

x = mungesomedict(dict(adict, **anotherdict))

내 코드에서 합리적으로 자주 발생합니다.

Alex Martelli가 처음 제출 함

참고 : Python 3에서는 basket_two의 모든 키가 a 인 경우에만 작동합니다 string.


3
에 대한 설명서 dict는 찾기 쉽지만 **조금 더 까다 롭습니다 (키워드는 kwargs입니다 ). 여기에 좋은 설명이 있습니다 : saltycrane.com/blog/2008/01/…
johndodo

4
이것은 단일 명령으로 두 번째 변수를 생성하는 데 사용될 수 있지만 basket_one.update(<dict>), 이름에서 알 수 있듯이 기존 사전 (또는 복제 된 사전)을 업데이트합니다.
furins

2
Python 3에서 인수 이름과 따라서 키는 **anotherdict문자열이어야합니다.
Petr Viktorin

감사합니다 @ johndodo-귀하의 제안을 게시물에 통합했습니다.
Tom Leys

1
허용되는 답변에 대한 훌륭한 기능 대안입니다. 이 방법은 새로 결합 된 dict를 직접 사용해야하는 경우에 바람직합니다. (또한 허용되는 답변에 대한 @ e18r의 의견 참조).
chinnychinchin

45

사전 매핑과 함께 사전 이해를 사용해 보셨습니까?

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

c = {**a, **b}
# c = {"a": 1, "b": 2, "c": 3, "d": 4}

또 다른 방법은 dict (iterable, ** kwarg)를 사용하는 것입니다

c = dict(a, **b)
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

Python 3.9에서는 union | 운영자

# use the merging operator |
c = a | b
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

5
참고 : 이것은 Python 2.7에서 유효한 구문이 아닙니다
Asav Patel

2
이 문법은 상당히 새롭습니다 (Python 3.5)
pianoJames

24
a.update(b)

에서 키와 값을 추가합니다 B 에 이미 키에 대한 값이 있다면 덮어 씁니다.


17

다른 사람이 언급 한 바와 같이 a.update(b)일부 dicts을 위해 a그리고 b당신은 당신의 질문에 요구 한 결과를 얻을 것입니다. 그러나 extend객체 매핑 / 설정 방법이 구문 a.extend(b)에서 a값을 값으로 덮어 쓰지 않아야 한다는 것을 여러 번 보았 음을 지적하고 싶습니다 b. 의 값을 a.update(b)덮어 쓰 a므로에 적합하지 않습니다 extend.

일부 언어는이 메소드를 호출합니다 defaults또는 inject이미있을 수있는 값을 덮어 쓰지 않고 사전에에서 (기본 값 세트 수 있습니다) B의 값을 주입하는 방법으로 생각 될 수있는.

물론, 당신 a.extend(b)은 거의 같은 메모를 할 수 b.update(a); a=b있습니다. 과제를 제거하려면 다음과 같이하면됩니다.

def extend(a,b):
    """Create a new dictionary with a's properties extended by b,
    without overwriting.

    >>> extend({'a':1,'b':2},{'b':3,'c':4})
    {'a': 1, 'c': 4, 'b': 2}
    """
    return dict(b,**a)

에 부작용이없는 dict생성자를 사용하는 스마트 아이디어에 대한 Tom Leys에게 감사합니다 extend.


1

python 3.3에서 도입 된 python 's collections.Chainmap 을 사용할 수도 있습니다 .

from collections import Chainmap
c = Chainmap(a, b)
c['a'] # returns 1

사용 사례에 따라 몇 가지 장점이 있습니다. 여기 에 더 자세히 설명되어 있지만 간단한 개요를 제공합니다.

  • 체인 맵은 사전보기 만 사용하므로 실제로 데이터가 복사되지 않습니다. 결과적으로 체인 속도가 빨라지지만 조회 속도는 느려집니다.
  • 실제로 덮어 쓰는 키가 없으므로 필요한 경우 데이터가 a인지 b인지를 알 수 있습니다.

이것은 주로 구성 사전과 같은 것들에 유용합니다.


0

당신이 그것을 필요로하는 경우 Class dict로 확장하고 update 메소드를 사용할 수 있습니다 .

Class a(dict):
  # some stuff
  self.update(b)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.