사전에서 여러 키를 안전하게 제거
항목을 제거하는 방법을 알고 있습니다.'key'
내 사전에서.d
안전하게사용자:
if d.has_key('key'):
del d['key']
그러나 사전에서 여러 항목을 안전하게 제거해야 합니다.이 작업을 두 번 이상 수행해야 하기 때문에 항목을 튜플로 정의하려고 합니다.
entities_to_remove = ('a', 'b', 'c')
for x in entities_to_remove:
if x in d:
del d[x]
하지만, 저는 이것을 하는 더 똑똑한 방법이 있는지 궁금합니다.
사용:
d = {'some': 'data'}
entries_to_remove = ('any', 'iterable')
for k in entries_to_remove:
d.pop(k, None)
딕트 이해 사용
final_dict = {key: value for key, value in d if key not in [key1, key2]}
여기서 key1 및 key2를 제거합니다.
아래 예제에서는 키 "b"와 "c"를 제거하고 키 목록에 유지합니다.
>>> a
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
>>> keys = ["b", "c"]
>>> print {key: a[key] for key in a if key not in keys}
{'a': 1, 'd': 4}
>>>
이렇게 하는 게 어때요?
entries = ('a', 'b', 'c')
the_dict = {'b': 'foo'}
def entries_to_remove(entries, the_dict):
for key in entries:
if key in the_dict:
del the_dict[key]
mattbornski는 dict.pop()을 사용하여 보다 컴팩트한 버전을 제공했습니다.
해결책이 사용되고 있습니다.map
그리고.filter
파이썬 2
d={"a":1,"b":2,"c":3}
l=("a","b","d")
map(d.__delitem__, filter(d.__contains__,l))
print(d)
파이썬 3
d={"a":1,"b":2,"c":3}
l=("a","b","d")
list(map(d.__delitem__, filter(d.__contains__,l)))
print(d)
다음과 같은 정보를 얻을 수 있는 것:
{'c': 3}
제거할 키의 값도 검색해야 하는 경우 이 방법을 사용하는 것이 좋습니다.
values_removed = [d.pop(k, None) for k in entities_to_remove]
물론 키를 제거하는 것만으로도 이 작업을 수행할 수 있습니다.d
하지만 당신은 목록 이해력이 있는 값 목록을 불필요하게 만들 것입니다.함수의 부작용만을 위해 목록 이해를 사용하는 것도 약간 불분명합니다.
다음을 통해 솔루션을 찾았습니다.pop
그리고.map
d = {'a': 'valueA', 'b': 'valueB', 'c': 'valueC', 'd': 'valueD'}
keys = ['a', 'b', 'c']
list(map(d.pop, keys))
print(d)
이 결과는 다음과 같습니다.
{'d': 'valueD'}
이 질문에 답을 늦게 한 이유는 누구나 같은 검색을 하면 앞으로 도움이 될 것 같아서입니다.그리고 이것은 도움이 될 수 있습니다.
갱신하다
위의 코드는 딕트에 키가 존재하지 않으면 오류를 발생시킵니다.
DICTIONARY = {'a': 'valueA', 'b': 'valueB', 'c': 'valueC', 'd': 'valueD'}
keys = ['a', 'l', 'c']
def remove_key(key):
DICTIONARY.pop(key, None)
list(map(remove_key, keys))
print(DICTIONARY)
출력:
DICTIONARY = {'b': 'valueB', 'd': 'valueD'}
cpython 3에 대한 일부 타이밍 테스트는 루프를 위한 간단한 방법이 가장 빠른 방법임을 보여주며, 꽤 읽기 쉽습니다.함수를 추가해도 오버헤드가 크지 않습니다.
결과 시간(10k 반복):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
def del_all(mapping, to_remove):
"""Remove list of elements from mapping."""
for key in to_remove:
del mapping[key]
작은 반복의 경우 함수 호출의 오버헤드 때문에 '인라인'을 수행하는 것이 조금 더 빠릅니다.그렇지만del_all
는 보풀 안전하고 재사용 가능하며 모든 파이썬 이해 및 매핑 구성보다 빠릅니다.
기존 답변에는 문제가 없지만, 이 솔루션을 찾지 못해 놀랐습니다.
keys_to_remove = ['a', 'b', 'c']
my_dict = {k: v for k, v in zip("a b c d e f g".split(' '), [0, 1, 2, 3, 4, 5, 6])}
for k in keys_to_remove:
try:
del my_dict[k]
except KeyError:
pass
assert my_dict == {'d': 3, 'e': 4, 'f': 5, 'g': 6}
참고: 저는 여기서 우연히 이 질문을 발견했습니다.그리고 제 대답은 이 대답과 관련이 있습니다.
세 가지 방법의 성능을 테스트했습니다.
# Method 1: `del`
for key in remove_keys:
if key in d:
del d[key]
# Method 2: `pop()`
for key in remove_keys:
d.pop(key, None)
# Method 3: comprehension
{key: v for key, v in d.items() if key not in remove_keys}
다음은 1M 반복의 결과입니다.
del
2 2.03s 2.0ns/리터(100%)pop()
2 ( 2.38s 2.4ns/iter (117%)- 이해력: 4.11s 4.1ns/iter (202%)
그래서 둘 다del
그리고.pop()
가장 빠릅니다.이해 속도가 2배 느립니다.하지만 어쨌든, 우리는 여기서 나노초를 말합니다 :) 파이썬의 딕트는 터무니없이 빠릅니다.
그렇지 않은 이유:
entriestoremove = (2,5,1)
for e in entriestoremove:
if d.has_key(e):
del d[e]
"똑똑한 방법"이 무슨 뜻인지 모르겠습니다.물론 사전적 이해를 통해 다른 방법이 있을 수 있습니다.
entriestoremove = (2,5,1)
newdict = {x for x in d if x not in entriestoremove}
인라인의
import functools
#: not key(c) in d
d = {"a": "avalue", "b": "bvalue", "d": "dvalue"}
entitiesToREmove = ('a', 'b', 'c')
#: python2
map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove)
#: python3
list(map(lambda x: functools.partial(d.pop, x, None)(), entitiesToREmove))
print(d)
# output: {'d': 'dvalue'}
키를 세트로 취급할 수 있다는 사실을 사용하는 것이 파이썬 3에 있다면 가장 좋은 방법이라고 생각합니다.
def remove_keys(d, keys):
to_remove = set(keys)
filtered_keys = d.keys() - to_remove
filtered_values = map(d.get, filtered_keys)
return dict(zip(filtered_keys, filtered_values))
예:
>>> remove_keys({'k1': 1, 'k3': 3}, ['k1', 'k2'])
{'k3': 3}
키 집합을 "제거"할 수 있도록 사전 세트 메소드(Python 3.9에서 발생하는 끔찍한 혼란이 아니라)를 완전히 지원하는 것이 좋습니다.그러나 제거할 키가 많은 대형 사전이 있는 경우에는 성능에 대해 알고 싶을 수도 있습니다.그래서, 저는 의미 있는 비교를 할 수 있을 만큼 충분히 큰 것을 만드는 코드를 만들었습니다. 100,000 x 1000 행렬, 그러니까 총 10,000,00개 항목입니다.
from itertools import product
from time import perf_counter
# make a complete worksheet 100000 * 1000
start = perf_counter()
prod = product(range(1, 100000), range(1, 1000))
cells = {(x,y):x for x,y in prod}
print(len(cells))
print(f"Create time {perf_counter()-start:.2f}s")
clock = perf_counter()
# remove everything above row 50,000
keys = product(range(50000, 100000), range(1, 100))
# for x,y in keys:
# del cells[x, y]
for n in map(cells.pop, keys):
pass
print(len(cells))
stop = perf_counter()
print(f"Removal time {stop-clock:.2f}s")
1,000만 개 이상의 항목은 일부 설정에서 일반적이지 않습니다.로컬 컴퓨터에서 두 가지 방법을 비교해 보면 사용 시 약간의 개선이 있음을 알 수 있습니다.map
그리고.pop
아마도 함수 호출 수가 적기 때문이겠지만, 둘 다 내 기계에서 약 2.5초를 사용합니다.그러나 이는 사전을 만드는 데 필요한 시간(55초)이나 루프 내의 검사를 포함하는 데 필요한 시간에 비해 부족합니다.이 경우 사전 키와 필터가 교차하는 집합을 만드는 것이 가장 좋습니다.
keys = cells.keys() & keys
요약:del
이미 매우 최적화되어 있으므로 사용에 대해 걱정할 필요가 없습니다.
사전에서 키 목록을 제거하는 다른 맵() 방법
KeyError 예외를 발생시키지 마십시오.
dic = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
keys_to_remove = ['key_not_exist', 'key1', 'key2', 'key3']
k = list(map(dic.pop, keys_to_remove, keys_to_remove))
print('k=', k)
print('dic after = \n', dic)
**this will produce output**
k= ['key_not_exist', 1, 2, 3]
dic after = {'key4': 4, 'key5': 5}
중복keys_to_remove
인위적이므로 dict.pop() 함수에 대한 기본값을 제공해야 합니다.len_ = len(key_to_remove)으로 배열을 추가할 수 있습니다.
예를들면
dic = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
keys_to_remove = ['key_not_exist', 'key1', 'key2', 'key3']
k = list(map(dic.pop, keys_to_remove, np.zeros(len(keys_to_remove))))
print('k=', k)
print('dic after = ', dic)
출력 **을 생성합니다.
k= [0.0, 1, 2, 3]
dic after = {'key4': 4, 'key5': 5}
def delete_keys_from_dict(dictionary, keys):
"""
Deletes the unwanted keys in the dictionary
:param dictionary: dict
:param keys: list of keys
:return: dict (modified)
"""
from collections.abc import MutableMapping
keys_set = set(keys)
modified_dict = {}
for key, value in dictionary.items():
if key not in keys_set:
if isinstance(value, list):
modified_dict[key] = list()
for x in value:
if isinstance(x, MutableMapping):
modified_dict[key].append(delete_keys_from_dict(x, keys_set))
else:
modified_dict[key].append(x)
elif isinstance(value, MutableMapping):
modified_dict[key] = delete_keys_from_dict(value, keys_set)
else:
modified_dict[key] = value
return modified_dict
_d = {'a': 1245, 'b': 1234325, 'c': {'a': 1245, 'b': 1234325}, 'd': 98765,
'e': [{'a': 1245, 'b': 1234325},
{'a': 1245, 'b': 1234325},
{'t': 767}]}
_output = delete_keys_from_dict(_d, ['a', 'b'])
_expected = {'c': {}, 'd': 98765, 'e': [{}, {}, {'t': 767}]}
print(_expected)
print(_output)
다른 사람 말고는 이 토론에 늦었습니다.이러한 키 목록을 만드는 것이 해결책일 수 있습니다.
k = ['a','b','c','d']
그런 다음 목록 이해에서 pop()을 사용하거나 루프에 대해 pop()을 사용하여 키 위에서 반복하고 한 번에 하나씩 팝합니다.
new_dictionary = [dictionary.pop(x, 'n/a') for x in k]
'n/a'는 키가 존재하지 않는 경우 기본값을 반환해야 합니다.
언급URL : https://stackoverflow.com/questions/8995611/removing-multiple-keys-from-a-dictionary-safely
'programing' 카테고리의 다른 글
C 프로그래밍에서 배열에 요소를 추가하는 방법을 설명할 수 있는 사람이 있습니까? (0) | 2023.06.30 |
---|---|
Giton 비트 버킷:공용 SSH 키를 업로드한 후에도 항상 암호를 요청함 (0) | 2023.06.30 |
vuex 지속 상태가 vue 라우터 탐색 가드와 함께 작동하지 않음 (0) | 2023.06.30 |
Spring Boot: @Value는 항상 null을 반환합니다. (0) | 2023.06.30 |
dplyr을 사용하여 그룹별 행 수 계산 (0) | 2023.06.30 |