임의의 수의 kwargs 를 사용하고 해당 kwargs 를 포함하는 데이터베이스와 같은 목록의 요소를 포함하는 목록을 반환 하는 사용자 지정 필터 메서드를 작성하려고합니다 .
예를 들어, d1 = {'a':'2', 'b':'3'}
and d2
= 같은 것을 가정 하십시오. d1 == d2
True가됩니다. 그러나 d2
= 같은 것 + 다른 것들이 있다고 가정 하십시오. 내 방법 은 d2의 d1 인지 알 수 있어야 하지만 파이썬은 사전으로 그렇게 할 수 없습니다.
문맥:
Word 클래스가 있고 각 개체에는 word
,, definition
등의 속성이 있습니다 part_of_speech
. 이 단어의 기본 목록에서 필터 메서드를 호출 할 수 있기를 원합니다 Word.objects.filter(word='jump', part_of_speech='verb-intransitive')
. 이 키와 값을 동시에 관리하는 방법을 알 수 없습니다. 그러나 이것은 다른 사람들을 위해이 컨텍스트 밖에서 더 큰 기능을 가질 수 있습니다.
답변
항목 쌍으로 변환하고 격리를 확인하십시오.
all(item in superset.items() for item in subset.items())
최적화는 독자를위한 연습으로 남겨집니다.
답변
Python 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)
답변
단위 테스트를 위해 이것을 필요로하는 사람들을위한 참고 : assertDictContainsSubset()
Python의 TestCase
클래스 에도 메서드가 있습니다.
그러나 3.2에서는 더 이상 사용되지 않으며 이유가 확실하지 않으며 대체가있을 수 있습니다.
답변
키 및 값 확인 사용 :
set(d1.items()).issubset(set(d2.items()))
키만 확인해야하는 경우 :
set(d1).issubset(set(d2))
답변
완전성을 위해 다음을 수행 할 수도 있습니다.
def is_subdict(small, big):
return dict(big, **small) == big
그러나 나는 속도 (또는 속도 부족) 또는 가독성 (또는 부족)과 관련하여 어떠한 주장도하지 않습니다.
답변
>>> 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
>>>
답변
같은 목적으로 내 기능을 재귀 적으로 수행합니다.
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 type(pvalue) is dict
절 을 피하고 더 넓은 범위의 경우 (해시 목록 등)에 적용 하는 더 나은 솔루션이있을 수 있습니다 . 또한 재귀는 여기에 제한되지 않으므로 자신의 책임하에 사용하십시오. 😉