[PYTHON] 파이썬 : 한 사전이 다른 큰 사전의 하위 집합인지 확인하십시오
PYTHON파이썬 : 한 사전이 다른 큰 사전의 하위 집합인지 확인하십시오
나는 임의의 수의 kwargs를 취하여 해당 kwargs를 포함하는 데이터베이스와 같은 목록 요소를 포함하는 목록을 반환하는 사용자 지정 필터 메서드를 작성하려고합니다.
예를 들어, d1 = { 'a': '2', 'b': '3'} 및 d2 = 같은 것으로 가정하십시오. d1 == d2 결과는 참입니다. 그러나 d2 = 같은 것을 더한 다른 것들을 생각 해보자. 내 방법은 d2가 d1인지 알 수 있어야하지만 파이썬은 사전을 사용하여이를 수행 할 수 없다.
문맥:
저는 Word 클래스를 가지고 있으며 각 객체는 word, definition, part_of_speech 등과 같은 속성을 가지고 있습니다. Word.objects.filter (word = 'jump', part_of_speech = 'verb-intransitive')와 같이 이러한 단어의 기본 목록에서 필터 메서드를 호출 할 수 있기를 원합니다. 나는이 키와 값을 동시에 관리하는 방법을 알 수 없다. 그러나 이것은 다른 사람들을 위해이 문맥 밖에서 더 큰 기능을 가질 수 있습니다.
해결법
-
==============================
1.항목 쌍으로 변환하고 포함을 확인하십시오.
항목 쌍으로 변환하고 포함을 확인하십시오.
all(item in superset.items() for item in subset.items())
최적화는 독자의 연습 과제로 남겨 둡니다.
-
==============================
2.파이썬 3에서는 dict.items ()를 사용하여 dict 항목의 집합과 같은보기를 얻을 수 있습니다. 그런 다음 <= 연산자를 사용하여 한 뷰가 다른 뷰의 "하위 세트"인지 테스트 할 수 있습니다.
파이썬 3에서는 dict.items ()를 사용하여 dict 항목의 집합과 같은보기를 얻을 수 있습니다. 그런 다음 <= 연산자를 사용하여 한 뷰가 다른 뷰의 "하위 세트"인지 테스트 할 수 있습니다.
d1.items() <= d2.items()
Python 2.7에서는 dict.viewitems ()를 사용하여 동일한 작업을 수행합니다.
d1.viewitems() <= d2.viewitems()
Python 2.6 이하에서는 all ()을 사용하는 것과 같은 다른 해결책이 필요합니다.
all(key in d2 and d2[key] == d1[key] for key in d1)
-
==============================
3.단위 테스트를 위해 필요한 사람을위한 노트 : 파이썬의 TestCase 클래스에는 assertDictContainsSubset () 메소드가있다.
단위 테스트를 위해 필요한 사람을위한 노트 : 파이썬의 TestCase 클래스에는 assertDictContainsSubset () 메소드가있다.
http://docs.python.org/2/library/unittest.html?highlight=assertdictcontainssubset#unittest.TestCase.assertDictContainsSubset
그러나 3.2에서 더 이상 사용되지 않는 이유가 무엇인지, 어쩌면 대체 할 수 있을지도 모릅니다.
-
==============================
4.키 및 값 확인 용도 : set (d1.items ()). issubset (set (d2.items ()))
키 및 값 확인 용도 : set (d1.items ()). issubset (set (d2.items ()))
키만 확인해야하는 경우 : set (d1) .issubset (set (d2))
-
==============================
5.완전성을 위해 다음 작업을 수행 할 수도 있습니다.
완전성을 위해 다음 작업을 수행 할 수도 있습니다.
def is_subdict(small, big): return dict(big, **small) == big
그러나 나는 속도 (또는 그 부족) 또는 가독성 (또는 그 부족)과 관련하여 어떠한 주장도하지 않습니다.
-
==============================
6.
>>> d1 = {'a':'2', 'b':'3'} >>> d2 = {'a':'2', 'b':'3','c':'4'} >>> all((k in d2 and d2[k]==v) for k,v in d1.iteritems()) True
문맥:
>>> d1 = {'a':'2', 'b':'3'} >>> d2 = {'a':'2', 'b':'3','c':'4'} >>> list(d1.iteritems()) [('a', '2'), ('b', '3')] >>> [(k,v) for k,v in d1.iteritems()] [('a', '2'), ('b', '3')] >>> k,v = ('a','2') >>> k 'a' >>> v '2' >>> k in d2 True >>> d2[k] '2' >>> k in d2 and d2[k]==v True >>> [(k in d2 and d2[k]==v) for k,v in d1.iteritems()] [True, True] >>> ((k in d2 and d2[k]==v) for k,v in d1.iteritems()) <generator object <genexpr> at 0x02A9D2B0> >>> ((k in d2 and d2[k]==v) for k,v in d1.iteritems()).next() True >>> all((k in d2 and d2[k]==v) for k,v in d1.iteritems()) True >>>
-
==============================
7.재귀 적으로이 일을하는 같은 목적을위한 내 함수 :
재귀 적으로이 일을하는 같은 목적을위한 내 함수 :
def dictMatch(patn, real): """does real dict match pattern?""" try: for pkey, pvalue in patn.iteritems(): if type(pvalue) is dict: result = dictMatch(pvalue, real[pkey]) assert result else: assert real[pkey] == pvalue result = True except (AssertionError, KeyError): result = False return result
귀하의 예제에서, dictMatch (d1, d2)는 d2가 다른 것들을 가지고 있어도 True를 리턴해야하며, 더 낮은 레벨에도 적용됩니다 :
d1 = {'a':'2', 'b':{3: 'iii'}} d2 = {'a':'2', 'b':{3: 'iii', 4: 'iv'},'c':'4'} dictMatch(d1, d2) # True
참고 사항 : if 형식 (pvalue)이 dict 절이며 피연산자가 더 넓은 범위 (예 : 해시 목록 등)에 적용되는 더 나은 솔루션이있을 수 있습니다. 또한 여기에는 재귀가 제한되지 않으므로 사용자의 책임하에 사용하십시오. ;)
-
==============================
8.이 겉으로보기에는 간단한 문제는 100 % 신뢰할 수있는 솔루션을 찾기 위해 조사에서 두 시간의 비용이 들었으므로이 답변에서 내가 찾은 것을 문서화했습니다.
이 겉으로보기에는 간단한 문제는 100 % 신뢰할 수있는 솔루션을 찾기 위해 조사에서 두 시간의 비용이 들었으므로이 답변에서 내가 찾은 것을 문서화했습니다.
-
==============================
9.다음은 주어진 문제에 대한 일반적인 재귀 적 솔루션입니다.
다음은 주어진 문제에 대한 일반적인 재귀 적 솔루션입니다.
import traceback import unittest def is_subset(superset, subset): for key, value in subset.items(): if key not in superset: return False if isinstance(value, dict): if not is_subset(superset[key], value): return False elif isinstance(value, str): if value not in superset[key]: return False elif isinstance(value, list): if not set(value) <= set(superset[key]): return False elif isinstance(value, set): if not value <= superset[key]: return False else: if not value == superset[key]: return False return True class Foo(unittest.TestCase): def setUp(self): self.dct = { 'a': 'hello world', 'b': 12345, 'c': 1.2345, 'd': [1, 2, 3, 4, 5], 'e': {1, 2, 3, 4, 5}, 'f': { 'a': 'hello world', 'b': 12345, 'c': 1.2345, 'd': [1, 2, 3, 4, 5], 'e': {1, 2, 3, 4, 5}, 'g': False, 'h': None }, 'g': False, 'h': None, 'question': 'mcve', 'metadata': {} } def tearDown(self): pass def check_true(self, superset, subset): return self.assertEqual(is_subset(superset, subset), True) def check_false(self, superset, subset): return self.assertEqual(is_subset(superset, subset), False) def test_simple_cases(self): self.check_true(self.dct, {'a': 'hello world'}) self.check_true(self.dct, {'b': 12345}) self.check_true(self.dct, {'c': 1.2345}) self.check_true(self.dct, {'d': [1, 2, 3, 4, 5]}) self.check_true(self.dct, {'e': {1, 2, 3, 4, 5}}) self.check_true(self.dct, {'f': { 'a': 'hello world', 'b': 12345, 'c': 1.2345, 'd': [1, 2, 3, 4, 5], 'e': {1, 2, 3, 4, 5}, }}) self.check_true(self.dct, {'g': False}) self.check_true(self.dct, {'h': None}) def test_tricky_cases(self): self.check_true(self.dct, {'a': 'hello'}) self.check_true(self.dct, {'d': [1, 2, 3]}) self.check_true(self.dct, {'e': {3, 4}}) self.check_true(self.dct, {'f': { 'a': 'hello world', 'h': None }}) self.check_false( self.dct, {'question': 'mcve', 'metadata': {'author': 'BPL'}}) self.check_true( self.dct, {'question': 'mcve', 'metadata': {}}) self.check_false( self.dct, {'question1': 'mcve', 'metadata': {}}) if __name__ == "__main__": unittest.main()
참고 : 원래 코드는 특정 경우에 실패 할 것이고, 수정에 대한 크레딧은 @ olivier-melançon으로갑니다.
-
==============================
10.이 함수는 해시 가능하지 않은 값에 대해 작동합니다. 나는 또한 그것이 명확하고 읽기 쉽다고 생각한다.
이 함수는 해시 가능하지 않은 값에 대해 작동합니다. 나는 또한 그것이 명확하고 읽기 쉽다고 생각한다.
def isSubDict(subDict,dictionary): for key in subDict.keys(): if (not key in dictionary) or (not subDict[key] == dictionary[key]): return False return True In [126]: isSubDict({1:2},{3:4}) Out[126]: False In [127]: isSubDict({1:2},{1:2,3:4}) Out[127]: True In [128]: isSubDict({1:{2:3}},{1:{2:3},3:4}) Out[128]: True In [129]: isSubDict({1:{2:3}},{1:{2:4},3:4}) Out[129]: False
-
==============================
11.나는이 질문이 오래되었다는 것을 알고 있지만, 하나의 중첩 된 사전이 다른 중첩 된 사전의 일부인지 확인하기위한 나의 해결책이다. 해는 재귀 적입니다.
나는이 질문이 오래되었다는 것을 알고 있지만, 하나의 중첩 된 사전이 다른 중첩 된 사전의 일부인지 확인하기위한 나의 해결책이다. 해는 재귀 적입니다.
def compare_dicts(a, b): for key, value in a.items(): if key in b: if isinstance(a[key], dict): if not compare_dicts(a[key], b[key]): return False elif value != b[key]: return False else: return False return True
from https://stackoverflow.com/questions/9323749/python-check-if-one-dictionary-is-a-subset-of-another-larger-dictionary by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬 예외 / 오류 계층 구조 인쇄 (0) | 2018.11.17 |
---|---|
[PYTHON] numpy에서 인접하지 않은 범위를 여러 개 색인으로 만듭니다. (0) | 2018.11.17 |
[PYTHON] 왜 클래스 __dict__는 mappingproxy입니까? (0) | 2018.11.16 |
[PYTHON] HTML 표를 JSON으로 변환 (0) | 2018.11.16 |
[PYTHON] 파이썬에서 나선형 배열을 만드는가? (0) | 2018.11.16 |