파이썬 사전에서 키를 제거하는 방법?


답변:


2836

사전에 있는지 여부에 관계없이 키를 삭제하려면 다음과 같이 두 개의 인수 형식을 사용하십시오 dict.pop().

my_dict.pop('key', None)

이 반환 my_dict[key]되면 key사전에 존재하며, None그렇지. 두 번째 매개 변수가 지정되지 않은 (즉. 경우 my_dict.pop('key')) 및 key존재하지 않는하는이 KeyError발생합니다.

존재한다고 보장되는 키를 삭제하려면 다음을 사용할 수도 있습니다.

del my_dict['key']

KeyError키가 사전에 없으면 키를 올립니다 .


152
때로는 pop()over 사용의 이점 del: 해당 키의 값을 반환합니다. 이렇게하면 한 줄의 코드로 dict에서 항목을 가져오고 삭제할 수 있습니다.
kratenko

7
문제에서 가치를 유지할 필요는 없습니다. 이것은 불필요한 복잡성 만 추가합니다. @zigg (아래)의 대답이 훨씬 좋습니다.
Salvatore Cosentino 2016 년

10
@SalvatoreCosentino 나는 당신의 주장을 따를 수 없습니다. 이 답변의 코드가 다른 답변의 코드보다 어떻게 더 복잡합니까?
Sven Marnach 2016 년

33
@SalvatoreCosentino 아니요, 함수의 반환 값을 무시하는 것은 전혀 비효율적이지 않습니다. 정반대 –이 솔루션은 키가없는 경우 try/ except솔루션 보다 훨씬 빠릅니다 . 하나 또는 다른 것을 읽기가 더 쉽다는 것을 알 수 있습니다. 둘 다 관용적 인 파이썬이므로 원하는 것을 선택하십시오. 그러나이 답변이 더 복잡하거나 비효율적이라고 주장하는 것은 말이되지 않습니다.
Sven Marnach 2016 년

5
이해가 안 돼요. 이것이 어떻게 문제입니까? 파이썬의 내장 유형에 대한 메소드는 모두 반환 self하지 않으므로이 경우에는 다소 놀랍습니다.
스벤 마르 나치

352

구체적으로 "이 작업을 수행하는 한 가지 방법이 있습니까?"

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

... 음, 당신 은 물었다 ;-)

당신은에서 개체를 삭제하는이 방법이 있다고하지만, 고려해야 할 dict것입니다 원자하지 - 그것은 것은 그 수 'key'에있을 수 있습니다 my_dict동안 if문하지만, 전에 삭제 될 수 있습니다 del경우가있는, 실행 del실패합니다 KeyError. 이것을 감안할 때, 사용dict.pop 하거나 무언가를 사용하는 것이 가장 안전합니다.

try:
    del my_dict['key']
except KeyError:
    pass

물론 이것은 확실히 하나의 라이너가 아닙니다 .


27
그래, pop확실히 더 간결하지만, 이런 식으로하는 것의 주요 이점이 있습니다 : 그것은 무엇을하고 있는지 즉시 분명합니다.
zigg

4
try/except문은 더 비싸다. 예외 발생이 느립니다.
Chris Barker 5

16
@ChrisBarker 내가 찾은 키가 있다면 try조금 더 빠르지 만 try실제로는 그렇지 않습니다 . 존재하지 않는 키를 pop제외 try하고 는 상당히 일관성이 있지만 모두보다 느립니다 . gist.github.com/zigg/6280653을 참조하십시오 . 궁극적으로, 키가 실제로 사전에 얼마나 자주 있을지, 원 자성이 필요한지 여부, 그리고 물론 조기 최적화에 관여하는지 여부에 따라 달라집니다.)
zigg

9
나는 명확성의 가치를 간과해서는 안된다고 생각합니다. 이것을 위해 +1.
Juan Carlos Coto 2016 년

2
시도 / 제외 비용과 관련하여 귀하는 또한 갈 수 있습니다 if 'key' in mydict: #then del.... 올바르게 구문 분석하기 위해 dict에서 키 / val을 꺼내야했습니다. 팝은 완벽한 솔루션이 아닙니다.
Marc

152

정확히 무엇을하고 있는지 알아내는 데 시간이 걸렸습니다 my_dict.pop("key", None). 따라서 다른 인터넷 검색 시간을 절약하기 위해 이것을 답변으로 추가하겠습니다.

pop(key[, default])

가 사전에 있으면 키를 제거하고 값을 리턴하고 그렇지 않으면 기본값을 리턴하십시오 . 경우 기본값이 주어지지하고 키가 사전에없는, a는 KeyError발생합니다.

선적 서류 비치


15
파이썬 인터프리터에 help (dict.pop)를 입력하십시오.
David Mulder

13
무엇을하는지 알아야 할 때 help ()와 dir ()이 친구가 될 수 있습니다.
David Mulder

3
또는 dict.pop?IPython에서.
Erik Kaplun

50

del my_dict[key]my_dict.pop(key)키가 존재할 때 사전에서 키를 제거하는 것보다 약간 빠릅니다.

>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"

>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786

그러나 키가 존재하지 않을 if key in my_dict: del my_dict[key]때보 다 약간 빠릅니다 my_dict.pop(key, None). 모두는 적어도 세 배 빠른 속도로보다 delA의 try/ except문 :

>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
...     del d['missing key']
... except KeyError:
...     pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133

1
이러한 빠른 작업의 타이밍을 측정하는 것은 매우 어리 석습니다. 코드는 아마 당신이 변화하기 때문에 훨씬 빠르게 얻을하지 않을 popA를 del. 사전을 만들면 사전에서 물건을 완전히 삭제하는 것이 왜소합니다.
보리스

1
@Boris-이것은 일반적인 운동으로 유용합니다.
데이지

1
@daisy 내가 말하는 것은 300 나노초 더 빠른 연산이 아닌 가장 읽기 쉬운 구문을 선택해야한다는 것입니다 (말 그대로 첫 번째 타이밍 세트 del와 의 차이 pop)
Boris

또한 이러한 작업은 너무 빨라서 타이밍이 신뢰할 수 없습니다.
Boris

45

한 줄의 코드로 사전에서 많은 키를 제거 해야하는 경우 map () 사용은 간결하고 파이썬으로 읽을 수 있다고 생각합니다.

myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}

사전에없는 값을 표시 할 때 오류를 잡으려면 map () 안에 람다를 사용하십시오.

map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}

또는에서 python3대신 목록 이해를 사용해야합니다.

[myDict.pop(x, None) for x in ['a', 'c', 'e']]

효과가있다. myDict에 'e'키가 없더라도 'e'는 오류를 발생시키지 않았습니다.


42
파이썬 3에서는 map친구가 이제 게으르고 반복자를 반환 하기 때문에 작동하지 않습니다 . map부작용에 사용 하는 것은 일반적으로 나쁜 습관으로 간주됩니다. 표준 for ... in루프가 더 좋습니다. 자세한 내용 은 목록 대신보기 및 반복자 를 참조하십시오.
Greg Krimer

5
취향과 실습 스타일에 관계없이 목록 이해는 여전히 Py3 [myDict.pop(i, None) for i in ['a', 'c']]에서 작동해야 합니다 map(및 filter)에 대한 일반적인 대안을 제공합니다 .
Michael Ekoka

@MichaelEkoka 당신은 부작용에 대한 목록 이해를 사용해서는 안되며, 규칙적인 for ... in루프를 사용하십시오 .
보리스

@Boris 아마도 당신 말이 맞을 것입니다. 내 대답은 특히 map()부작용에 사용되는을 사용하는 것과 관련이 있습니다. 파이썬에서 권장되는 대안은 있다 내 의견으로는 여전히 한 줄 (질문 참조)와 같은 매우 읽기 및인지 적으로 빛이 목록의 이해. 부작용에만 사용되는 두 가지 구조 모두 실제로 쓸모없는 목록을 만들어 비효율적 일 수 있습니다. Python3부터는 비싼 부산물없이 생성기 표현식을 통해 안전하고 우아하게 반복 할 수있는 내장 함수를 알지 못합니다 (예 :) loop(d.pop(k) for k in ['a', 'b']).
Michael Ekoka

나는 항상 가장 많이 찬성 된 답변에 내가 사용하지 않을 해킹이 포함되어 있다는 것을 기쁘게 생각합니다. 제 생각에는 목록 이해 (옵션 3)가 가장 나쁜 접근법입니다. 저것을 사용하십시오.
마크 맥스 마이스터

19

사전 이해 를 사용하여 해당 키가 제거 된 새 사전을 작성할 수 있습니다 .

>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}

조건에 따라 삭제할 수 있습니다. key존재하지 않으면 오류 가 없습니다.



7

다음과 같은 접근 방식으로 파이썬 사전에서 키를 삭제할 수 있습니다.

del키워드를 사용하여 ; 그래도 거의 같은 접근 방식입니다-

 myDict = {'one': 100, 'two': 200, 'three': 300 }
 print(myDict)  # {'one': 100, 'two': 200, 'three': 300}
 if myDict.get('one') : del myDict['one']
 print(myDict)  # {'two': 200, 'three': 300}

또는

우리는 다음과 같이 할 수 있습니다 :

그러나이 과정에서 실제로 사전에서 특정 키를 제외 시키지 않고 사전에서 키를 삭제 하지는 않습니다 . 또한와 동일하지 않은 사전을 반환하는 것을 관찰했습니다 .myDict

myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}

우리가 쉘에서 그것을 실행하면, 그것은 {'five': 500, 'four': 400, 'three': 300, 'two': 200}같은 순서로 실행 되지 않습니다 myDict. 다시 인쇄하려고하면 myDict이 접근 방식으로 사전에서 제외한 키를 포함한 모든 키를 볼 수 있습니다. 그러나 다음 명령문을 변수에 지정하여 새 사전을 만들 수 있습니다.

var = {key:value for key, value in myDict.items() if key != 'one'}

이제 인쇄하려고하면 부모 명령을 따릅니다.

print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}

또는

pop()방법을 사용합니다 .

myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)

if myDict.get('one') : myDict.pop('one')
print(myDict)  # {'two': 200, 'three': 300}

의 차이 delpop그 사용 인 pop()방법을, 우리가 실제로 저장할 수있는 키의 값을 필요한 경우 다음과 같은 :

myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var)    # 100

유용한 경우 나중에 참조 할 수 있도록 요점을 포크 하십시오 .


1
if myDict.get('one')키가 있는지 확인하는 데 사용하지 마십시오 ! myDict [ 'one']에 잘못된 값이 있으면 실패합니다. 또한 dicts에는 고유 한 순서가 없으므로 언급하지 않는 것이 좋습니다.
Rob

@Rob dicts는 CPython 3.6으로 시작하는 삽입 순서와 3.7로 시작하는 다른 모든 Python 구현으로 정렬됩니다.
보리스

4

매우 장황하게하려면 예외 처리를 사용할 수 있습니다.

try: 
    del dict[key]

except KeyError: pass

그러나 pop()키가 없으면 방법 보다 속도가 느립니다 .

my_dict.pop('key', None)

몇 개의 키는 중요하지 않지만이 작업을 반복적으로 수행하는 경우 후자의 방법이 더 좋습니다.

가장 빠른 방법은 다음과 같습니다.

if 'key' in dict: 
    del myDict['key']

그러나이 방법은 'key'두 줄 사이에서 제거 하면 a KeyError가 발생 하기 때문에 위험 합니다.


1

나는 불변의 버전을 선호한다

foo = {
    1:1,
    2:2,
    3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
    return {
        k:v
        for k,v in dct.items() if k not in keyIter
    }

>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}

1

또 다른 방법은 items () + dict comprehension을 사용하는 것입니다.

dict 이해와 결합 된 items () 또한 키-값 쌍 삭제 작업을 수행하는 데 도움이 될 수 있지만, 적절한 dict 기술이 아닌 단점이 있습니다. 우리가 포함하고 싶지 않은 키를 제외하고는 실제로 새로운 dict가 만들어졌습니다.

test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21} 

# Printing dictionary before removal 
print ("dictionary before performing remove is : " + str(test_dict)) 

# Using items() + dict comprehension to remove a dict. pair 
# removes  vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'} 

# Printing dictionary after removal 
print ("dictionary after remove is : " + str(new_dict)) 

산출:

dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}

0

키의 단일 필터

  • "key"를 반환하고 my_dict에 "key"가 있으면 my_dict에서 제거하십시오.
  • my_dict에 "key"가 없으면 None을 반환합니다.

my_dict장소에서 변경 됩니다 (변경 가능)

my_dict.pop('key', None)

키의 다중 필터

새로운 dict 생성 (불변)

dic1 = {
    "x":1,
    "y": 2,
    "z": 3
}

def func1(item):
    return  item[0]!= "x" and item[0] != "y"

print(
    dict(
        filter(
            lambda item: item[0] != "x" and item[0] != "y", 
            dic1.items()
            )
    )
)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.