etc./StackOverFlow

사전에서 요소 삭제

청렴결백한 만능 재주꾼 2022. 1. 2. 04:54
반응형

질문자 :richzilla


Python의 사전에서 항목을 삭제하는 방법이 있습니까?

또한 사본을 반환하기 위해 사전에서 항목을 삭제하려면(즉, 원본을 수정하지 않음) 어떻게 해야 합니까?



del 은 요소를 제거합니다.

 del d[key]

이것은 기존 사전을 변경하므로 사전의 내용은 동일한 인스턴스에 대한 참조가 있는 다른 사람을 위해 변경됩니다. 사전을 반환하려면 사전을 복사하십시오.

 def removekey(d, key): r = dict(d) del r[key] return r

dict() 생성자는 얕은 복사본을 만듭니다. 전체 복사본을 만들려면 copy 모듈을 참조하십시오.


del /assignment/etc에 대한 사본을 만드는 것에 주의하십시오. 일정 시간에서 선형 시간으로 이동하고 선형 공간도 사용한다는 것을 의미합니다. 작은 dict의 경우 이것은 문제가 되지 않습니다. 그러나 큰 사전의 복사본을 많이 만들 계획이라면 아마도 HAMT와 같은 다른 데이터 구조를 원할 것입니다( 이 답변에 설명된 대로).


Greg Hewgill

pop 은 사전을 변경합니다.

 >>> lol = {"hello": "gdbye"} >>> lol.pop("hello") 'gdbye' >>> lol {}

원본을 유지하려면 복사하면 됩니다.


Crystal

귀하의 솔루션이 가장 좋은 방법이라고 생각합니다. 그러나 다른 솔루션을 원하면 다음과 같이 지정된 키를 포함하지 않고 이전 사전의 키를 사용하여 새 사전을 만들 수 있습니다.

 >>> a {0: 'zero', 1: 'one', 2: 'two', 3: 'three'} >>> {i:a[i] for i in a if i!=0} {1: 'one', 2: 'two', 3: 'three'}

utdemir

좋은 답변이 많이 있지만 한 가지만 강조하고 싶습니다.

dict.pop() 메서드와 보다 일반적인del 을 모두 사용하여 사전에서 항목을 제거할 수 있습니다. 둘 다 원래 사전을 변경하므로 사본을 만들어야 합니다(아래 세부 정보 참조).

제공하는 키가 사전에 없으면 둘 다 KeyError

 key_to_remove = "c" d = {"a": 1, "b": 2} del d[key_to_remove] # Raises `KeyError: 'c'`

그리고

 key_to_remove = "c" d = {"a": 1, "b": 2} d.pop(key_to_remove) # Raises `KeyError: 'c'`

당신은 이것을 돌봐야합니다:

예외를 캡처하여:

 key_to_remove = "c" d = {"a": 1, "b": 2} try: del d[key_to_remove] except KeyError as ex: print("No such key: '%s'" % ex.message)

그리고

 key_to_remove = "c" d = {"a": 1, "b": 2} try: d.pop(key_to_remove) except KeyError as ex: print("No such key: '%s'" % ex.message)

확인을 수행하여:

 key_to_remove = "c" d = {"a": 1, "b": 2} if key_to_remove in d: del d[key_to_remove]

그리고

 key_to_remove = "c" d = {"a": 1, "b": 2} if key_to_remove in d: d.pop(key_to_remove)

그러나 pop() 을 사용하면 훨씬 더 간결한 방법이 있습니다. 기본 반환 값을 제공하십시오.

 key_to_remove = "c" d = {"a": 1, "b": 2} d.pop(key_to_remove, None) # No `KeyError` here

제거할 키의 값을 가져오기 pop() 을 사용하지 않는 한 None 제공할 수 있습니다. del in check와 함께 사용하는 것이 오버헤드를 유발하는 자체 합병증이 있는 함수이기 때문에 pop() 이 약간 더 빠를 수 있습니다. 일반적으로 그렇지 않으므로 pop() 이면 충분합니다.


주요 질문에 관해서는, 원래 사전을 저장하고 키를 제거하지 않고 새 사전을 가지려면 사전의 사본을 만들어야 합니다.

copy.deepcopy() 를 사용하여 전체(깊은) 복사본을 만들 것을 제안 copy.copy() 또는 dict.copy() 사용하여 "정상적인"(얕은) 복사본이면 충분할 수 있습니다. . 사전은 키에 대한 값으로 개체에 대한 참조를 유지합니다. 따라서 사전에서 키를 제거하면 참조되는 객체가 아니라 이 참조가 제거됩니다. 객체 자체는 메모리에 다른 참조가 없는 경우 나중에 가비지 수집기에 의해 자동으로 제거될 수 있습니다. 깊은 복사를 만들려면 얕은 복사에 비해 더 많은 계산이 필요하므로 복사를 만들고 메모리를 낭비하고 GC에 더 많은 작업을 제공함으로써 코드 성능이 저하됩니다. 때로는 얕은 복사로도 충분합니다.

그러나 사전 값으로 변경 가능한 개체가 있고 키 없이 반환된 사전에서 나중에 수정하려는 경우 전체 복사본을 만들어야 합니다.

얕은 복사:

 def get_dict_wo_key(dictionary, key): """Returns a **shallow** copy of the dictionary without a key.""" _dict = dictionary.copy() _dict.pop(key, None) return _dict d = {"a": [1, 2, 3], "b": 2, "c": 3} key_to_remove = "c" new_d = get_dict_wo_key(d, key_to_remove) print(d) # {"a": [1, 2, 3], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3], "b": 2} new_d["a"].append(100) print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3, 100], "b": 2} new_d["b"] = 2222 print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}

딥 카피 사용:

 from copy import deepcopy def get_dict_wo_key(dictionary, key): """Returns a **deep** copy of the dictionary without a key.""" _dict = deepcopy(dictionary) _dict.pop(key, None) return _dict d = {"a": [1, 2, 3], "b": 2, "c": 3} key_to_remove = "c" new_d = get_dict_wo_key(d, key_to_remove) print(d) # {"a": [1, 2, 3], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3], "b": 2} new_d["a"].append(100) print(d) # {"a": [1, 2, 3], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3, 100], "b": 2} new_d["b"] = 2222 print(d) # {"a": [1, 2, 3], "b": 2, "c": 3} print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}

Nikita

del 문 은 당신이 찾고있는 것입니다. 'bar'라는 키가 있는 foo라는 사전이 있는 경우 다음과 같이 foo에서 'bar'를 삭제할 수 있습니다.

 del foo['bar']

이것은 작동 중인 사전을 영구적으로 수정합니다. 원본 사전을 유지하려면 사전에 사본을 만들어야 합니다.

 >>> foo = {'bar': 'baz'} >>> fu = dict(foo) >>> del foo['bar'] >>> print foo {} >>> print fu {'bar': 'baz'}

dict 호출은 얕은 복사본을 만듭니다. 전체 복사를 원하면 copy.deepcopy 사용하십시오.

다음은 편의를 위해 복사하여 붙여넣을 수 있는 방법입니다.

 def minus_key(key, dictionary): shallow_copy = dict(dictionary) del shallow_copy[key] return shallow_copy

arussell84

... 사본을 반환하기 위해 사전에서 항목을 삭제하려면(즉, 원본을 수정하지 않음) 어떻게 해야 합니까?

dict 는 이것을 사용하기에 잘못된 데이터 구조입니다.

물론, dict를 복사하고 복사본에서 팝핑하는 것은 작동하고 이해력이 있는 새 dict를 작성하는 것도 마찬가지이지만 복사하는 데 시간이 걸립니다. 그리고 살아있는 모든 사본은 한 번에 공간, 즉 사본당 선형 공간을 차지합니다.

해시 배열 매핑된 시도 와 같은 다른 데이터 구조는 정확히 이런 종류의 사용 사례를 위해 설계되었습니다. 요소를 추가하거나 제거 하면 원본과 대부분의 저장소를 공유하는 로그 시간에 복사본이 반환됩니다. 1

물론 몇 가지 단점이 있습니다. 성능은 일정하지 않고 대수입니다(비록 큰 밑, 일반적으로 32-128). 그리고 non-mutating API를 dict 와 동일하게 만들 수 있지만 "mutating" API는 분명히 다릅니다. 그리고 무엇보다도 Python에는 HAMT 배터리가 포함되어 있지 않습니다. 2

pyrsistent 라이브러리는 Python을 위한 HAMT 기반 dict-replacements(및 기타 다양한 유형)의 꽤 견고한 구현입니다. 기존 변경 코드를 가능한 한 원활하게 영구 코드로 이식하기 위한 멋진 진화 API도 있습니다. 그러나 변경하는 대신 복사본을 반환하는 것에 대해 명시적으로 하려면 다음과 같이 사용하면 됩니다.

 >>> from pyrsistent import m >>> d1 = m(a=1, b=2) >>> d2 = d1.set('c', 3) >>> d3 = d1.remove('a') >>> d1 pmap({'a': 1, 'b': 2}) >>> d2 pmap({'c': 3, 'a': 1, 'b': 2}) >>> d3 pmap({'b': 2})

d3 = d1.remove('a') 는 정확히 그 질문이 요구하는 것입니다.

pmap dictlist 임베딩된 변경 가능한 데이터 구조가 있는 경우 여전히 앨리어싱 문제가 있습니다. 불변으로 내려가 pmappvector 임베딩해야만 문제를 해결할 수 있습니다.


1. HAMT는 잠금이 없는 프로그래밍 및 소프트웨어 트랜잭션 메모리와 매우 잘 작동하기 때문에 Scala, Clojure, Haskell과 같은 언어에서도 인기를 얻었지만 둘 다 Python에서는 그다지 관련이 없습니다.

2. 사실의 구현에 사용되는 다음 stdlib에 HAMT, 거기 contextvars . 이전에 철회된 PEP는 그 이유를 설명합니다. 그러나 이것은 공개 컬렉션 유형이 아니라 라이브러리의 숨겨진 구현 세부 정보입니다.


abarnert

d = {1: 2, '2': 3, 5: 7} del d[5] print 'd = ', d

결과: d = {1: 2, '2': 3}


satels

간단히 del d['key']를 호출합니다.

그러나 프로덕션에서는 항상 '키'가 d에 있는지 확인하는 것이 좋습니다.

 if 'key' in d: del d['key']

Khanh Hua

# mutate/remove with a default ret_val = body.pop('key', 5) # no mutation with a default ret_val = body.get('key', 5)

daino3

아니, 방법이 없다.

 def dictMinus(dct, val): copy = dct.copy() del copy[val] return copy

그러나 종종 약간 변경된 사전의 복사본을 만드는 것은 비교적 큰 메모리 요구를 초래하기 때문에 좋은 생각이 아닐 수 있습니다. 일반적으로 이전 사전을 기록하고(필요한 경우에도) 수정하는 것이 좋습니다.


phihag

다음은 최상위 설계 접근 방식입니다.

 def eraseElement(d,k): if isinstance(d, dict): if k in d: d.pop(k) print(d) else: print("Cannot find matching key") else: print("Not able to delete") exp = {'A':34, 'B':55, 'C':87} eraseElement(exp, 'C')

사전과 원하는 키를 내 함수에 전달하고 사전인지 여부와 키가 괜찮은지 확인하고 둘 다 존재하는 경우 사전에서 값을 제거하고 남은 것을 인쇄합니다.

출력: {'B': 55, 'A': 34}

도움이 되기를 바랍니다!


codelox

>>> def delete_key(dict, key): ... del dict[key] ... return dict ... >>> test_dict = {'one': 1, 'two' : 2} >>> print delete_key(test_dict, 'two') {'one': 1} >>>

이것은 오류 처리를 수행하지 않으며 키가 사전에 있다고 가정합니다. 먼저 확인하고 그렇지 않은 경우 raise


tMC

아래 코드 스니펫이 확실히 도움이 될 것입니다. 코드를 이해하는 데 도움이 될 각 줄에 주석을 추가했습니다.

 def execute(): dic = {'a':1,'b':2} dic2 = remove_key_from_dict(dic, 'b') print(dict2) # {'a': 1} print(dict) # {'a':1,'b':2} def remove_key_from_dict(dictionary_to_use, key_to_delete): copy_of_dict = dict(dictionary_to_use) # creating clone/copy of the dictionary if key_to_delete in copy_of_dict : # checking given key is present in the dictionary del copy_of_dict [key_to_delete] # deleting the key from the dictionary return copy_of_dict # returning the final dictionary

또는 dict.pop()을 사용할 수도 있습니다.

 d = {"a": 1, "b": 2} res = d.pop("c") # No `KeyError` here print (res) # this line will not execute

또는 더 나은 접근 방식은

 res = d.pop("c", "key not found") print (res) # key not found print (d) # {"a": 1, "b": 2} res = d.pop("b", "key not found") print (res) # 2 print (d) # {"a": 1}

Mayur Agarwal

목록 이해를 사용하는 또 다른 변형은 다음과 같습니다.

 original_d = {'a': None, 'b': 'Some'} d = dict((k,v) for k, v in original_d.iteritems() if v) # result should be {'b': 'Some'}

접근 방식은 이 게시물의 답변을 기반으로 합니다 . 사전에서 빈 문자열이 있는 키를 제거하는 효율적인 방법


BigBlueHat

 species = {'HI': {'1': (1215.671, 0.41600000000000004), '10': (919.351, 0.0012), '1025': (1025.722, 0.0791), '11': (918.129, 0.0009199999999999999), '12': (917.181, 0.000723), '1215': (1215.671, 0.41600000000000004), '13': (916.429, 0.0005769999999999999), '14': (915.824, 0.000468), '15': (915.329, 0.00038500000000000003), 'CII': {'1036': (1036.3367, 0.11900000000000001), '1334': (1334.532, 0.129)}}

다음 코드는 dict species trans_HI 없는 항목을 삭제합니다.

 trans_HI=['1025','1215'] for transition in species['HI'].copy().keys(): if transition not in trans_HI: species['HI'].pop(transition)

Sameeresque

내 방법을 시도 할 수 있습니다. 한 줄에.

 yourList = [{'key':'key1','version':'1'},{'key':'key2','version':'2'},{'key':'key3','version':'3'}] resultList = [{'key':dic['key']} for dic in yourList if 'key' in dic] print(resultList)

Vincent55

출처 : http:www.stackoverflow.com/questions/5844672/delete-an-element-from-a-dictionary

반응형