파이썬은 존재하지 않는 경우 dict의 키를 업데이트합니다.


답변:


153

당신은 호출 할 필요는 없습니다 d.keys()때문에,

if key not in d:
    d[key] = value

충분합니다. 더 명확하고 읽기 쉬운 방법은 없습니다.

dict.get()키가 이미있는 경우 기존 값을 반환하는로 다시 업데이트 할 수 있습니다 .

d[key] = d.get(key, value)

그러나 나는 이것에 대해 강력히 권장합니다. 이것은 코드 골프, 유지 보수 및 가독성을 방해합니다.


코드를 사용하는 여러 스레드가있는 경우이를 동기화해야합니까?
ed22

1
@ ed22 yes, 스레드가 전환 할 수있는 여러 바이트 코드 명령으로 구성되어 있기 때문입니다.
Martijn Pieters

84

사용 dict.setdefault():

>>> d = {1: 'one'}
>>> d.setdefault(1, '1')
'one'
>>> d    # d has not changed because the key already existed
{1: 'one'}
>>> d.setdefault(2, 'two')
'two'
>>> d
{1: 'one', 2: 'two'}

6
dict.setdefault()값에 액세스하려고 할 때만 실제로 사용해야합니다.
Martijn Pieters

14
@MartijnPieters : 그게 왜 중요할까요? 이름 setdefault()은 무슨 일이 일어나고 있는지 명확하게 설명합니다. 값을 반환한다는 것은 그다지 중요하지 않으며 약간 기발한 IMO입니다. 이것이 바람직하지 않은 이유에 대해 빠른 설명이나 링크를 제공 할 수 있습니까?
mhawke

6
그룹화 루프에서와 같이 값이 존재할 것으로 예상하는 표현식에서 사용합니다 for obj in iterable: d.setdefault(key_for_obj(obj), []).append(obj). 반환되는 값에 대해 별난 것은 없습니다. 그것이 메소드의 요점입니다 .
Martijn Pieters

2
또한 이미 존재하지 않는 경우에만 키를 설정하려는 작업을가립니다. 가독성이 중요합니다. if key not in d:테스트를 사용하십시오 .
Martijn Pieters

7
@MartijnPieters : 설명해 주셔서 감사합니다. 독 스트링을 읽은 setdefault()것은 당신이 말한 것에 맞춰진 것 같습니다. a를 사용하면 defaultdict(list)예제보다 더 읽기 쉬운 코드가 생성되므로 표준 사전으로 작업해야하는 경우가 아니면 사용할 수 없습니다. 전반적 if key not in d으로 더 명확합니다.
mhawke

25

Python 3.9 부터 병합 연산자 | 를 사용하여 두 개의 사전을 병합 할 수 있습니다 . 오른쪽의 사전이 우선합니다.

new_dict = old_dict | { key: val }

예를 들면 :

new_dict = { 'a': 1, 'b': 2 } | { 'b': 42 }

print(new_dict} # {'a': 1, 'b': 42}

참고 : 이렇게하면 업데이트 된 값으로 새 사전이 생성됩니다.


6
이 재미 있지만, 나는 그것이 허용 대답보다 더 읽을 생각하지 않는다
저스틴 Furuness

2
저에게는 지금 두 개의 딕셔너리를 병합하는 방법이 있다는 것을 아는 것이 좋습니다
Austin A

이 병합에는 문제가 있습니다. 키가 동일하면 병합은 값을 무시합니다. 그것이 의도라면 작동합니다.
Joe Ferndz

1
@JoeFerndz 오른쪽의 사전이 우선권을 가지며 값을 무시하지 않습니다. 더 명확하게하기 위해 예제를 업데이트했습니다.
Rotareti

6

다음을 사용하여 여러 값을 삽입 할 수 있고 기본값도 가질 수 있지만 새 사전을 만듭니다.

d = {**{ key: value }, **default_values}

가장 많이 투표 한 답변으로 테스트했으며 평균적으로 다음 예제에서 볼 수 있듯이 더 빠릅니다.

for 루프 기반 방법을 unpack 연산자로 dict 이해와 비교하는 속도 테스트 for 루프 기반 방법을 unpack 연산자 방법으로 dict 이해와 비교하는 속도 테스트.

d = default_vals.copy()첫 번째 경우에 사본 ( )이 만들어 지지 않은 경우, 우리가 수십 배 10**5이상에 도달하면 가장 많이 투표 된 답변이 더 빨라질 것 입니다. 두 방법의 메모리 공간은 동일합니다.


1
그럼 왜 처음에 제안
조나단

1
이 솔루션은 나에게 완벽하게 유효 해 보입니다. 또한 하나의 선언에서 여러 값을 업데이트 할 수 있습니다.
Rotareti

정말 고맙습니다. 그러나이어야한다 보인다{**default_values, **{ key: value }}
osexp2003

0

위의 답변에 따르면 setdefault () 메서드가 저에게 효과적 이었습니다.

old_attr_name = mydict.setdefault(key, attr_name)
if attr_name != old_attr_name:
    raise RuntimeError(f"Key '{key}' duplication: "
                       f"'{old_attr_name}' and '{attr_name}'.")

이 솔루션은 일반적이지 않습니다. 이 특정한 경우에 저에게 딱 맞았습니다. 정확한 해결책은 key첫 번째를 확인하는 것입니다 (이미 권고 한대로).하지만 setdefault()사전에 대한 추가 조회를 피합니다. 즉, 작지만 여전히 성능이 향상됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.