Python의 키/값을 기반으로 사전을 필터링하고 하위 소설을 생성합니까?
-
06-07-2019 - |
문제
좋아, 나는 붙어있다. 여기서 도움이 필요하다 ...
다음과 같은 주요 사전이 있다면 다음과 같습니다.
data = [ {"key1": "value1", "key2": "value2", "key1": "value3"},
{"key1": "value4", "key2": "value5", "key1": "value6"},
{"key1": "value1", "key2": "value8", "key1": "value9"} ]
이제 일부 데이터를 형식화하려면 이미 해당 사전을 거쳐야합니다.
for datadict in data:
for key, value in datadict.items():
...filter the data...
이제 어떻게 든 같은 루프에서 어떻게 든 (가능하다면 ... 대안을 제안하십시오) 특정 키의 값을 점검하고 해당 값이 내 사전 설정과 일치하면 해당 전체 목록을 다른 사전에 추가하여 효과적으로 추가 할 것입니다. 특정 키와 값을 기반 으로이 메인 사전을 따라 가면서 작은 사전 생성?
따라서 Key1이 "value1"의 값을 갖는 모든 목록과 함께 하위 사전을 만들고 싶다고 가정 해 봅시다. 위의 목록에 대해 다음과 같은 내용을 줄 것입니다.
subdata = [ {"key1": "value1", "key2": "value2", "key1": "value3"},
{"key1": "value1", "key2": "value8", "key1": "value9"} ]
해결책
여기에 그렇게하는 방법이 없습니다. 결과는 생성기이지만 실제로 목록을 원한다면 전화로 둘러싸여 있습니다. list()
. 대부분은 중요하지 않습니다.
술어는 목록의 사전이 절단 될 경우 각 키/값 쌍에 대해 결정하는 함수입니다. 기본값은 모든 것을 받아들입니다. 사전에서 일치하는 데 k/v-pair가 없으면 거부됩니다.
def filter_data(data, predicate=lambda k, v: True):
for d in data:
for k, v in d.items():
if predicate(k, v):
yield d
test_data = [{"key1":"value1", "key2":"value2"}, {"key1":"blabla"}, {"key1":"value1", "eh":"uh"}]
list(filter_data(test_data, lambda k, v: k == "key1" and v == "value1"))
# [{'key2': 'value2', 'key1': 'value1'}, {'key1': 'value1', 'eh': 'uh'}]
다른 팁
다른 의견과 답변에서 이미 지적한 문제의 순 그물 (여러 동일한 키는 DICT 등에있을 수 없습니다). 내가하는 방법은 다음과 같습니다.
def select_sublist(list_of_dicts, **kwargs):
return [d for d in list_of_dicts
if all(d.get(k)==kwargs[k] for k in kwargs)]
subdata = select_sublist(data, key1='value1')
대답이 너무 간단하므로 정보가 누락 된 것 같습니다. 그래도:
result = []
for datadict in data:
for key, value in datadict.items():
thefiltering()
if datadict.get('matchkey') == 'matchvalue':
result.append(datadict)
또한, "메인 사전"은 사전이 아니라 목록입니다. 그냥 그것을 지우고 싶었습니다.
Skurmedal의 답변에서 영감을 얻은 나는 이것을 중첩 사전 데이터베이스와 함께 작업하기 위해 재귀 적 체계로 나뉘었다. 이 경우, "레코드"는 트렁크의 하위 분야입니다. 술어는 우리가 후에 어떤 레코드를 정의합니다 -이 쌍이 깊게 중첩 될 수있는 곳 (키, 값) 쌍과 일치하는 기록을 정의합니다.
def filter_dict(the_dict, predicate=lambda k, v: True):
for k, v in the_dict.iteritems():
if isinstance(v, dict) and _filter_dict_sub(predicate, v):
yield k, v
def _filter_dict_sub(predicate, the_dict):
for k, v in the_dict.iteritems():
if isinstance(v, dict) and filter_dict_sub(predicate, v):
return True
if predicate(k, v):
return True
return False
이것은 생성기이므로 dict(filter_dict(the_dict))
필터링 된 사전을 얻습니다.
오래된 질문이지만 어떤 이유로 든 한 라이너 구문 답변이 없습니다.
{ k: v for k, v in <SOURCE_DICTIONARY>.iteritems() if <CONDITION> }
예를 들어:
src_dict = { 1: 'a', 2: 'b', 3: 'c', 4: 'd' }
predicate = lambda k, v: k % 2 == 0
filtered_dict = { k: v for k, v in src_dict.iteritems() if predicate(k, v) }
print "Source dictionary:", src_dict
print "Filtered dictionary:", filtered_dict
다음 출력을 생성합니다.
Source dictionary: {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
Filtered dictionary: {2: 'b', 4: 'd'}