Jam*_*mey 91 python dictionary subset filter
我正在尝试编写一个自定义过滤器方法,它接受任意数量的kwargs并返回一个列表,其中包含类似数据库的列表,其中包含那些kwargs.
例如,假设d1 = {'a':'2', 'b':'3'}和d2=同样的事情.d1 == d2结果是真的.但是假设d2=同样的事情加上一堆其他的东西.我的方法需要能够判断d2中是否有d1,但Python不能用字典来表示.
语境:
我有一个字类,并且每个对象都有类似的属性word,definition,part_of_speech,等等.我希望能够在这些单词的主列表上调用过滤方法,例如Word.objects.filter(word='jump', part_of_speech='verb-intransitive').我无法弄清楚如何同时管理这些键和值.但是,对于其他人来说,这可能会在此背景下具有更大的功
Ign*_*ams 95
转换为项目对并检查包含.
all(item in superset.items() for item in subset.items())
Run Code Online (Sandbox Code Playgroud)
优化留给读者练习.
aug*_*rar 75
在Python 3中,您可以使用dict.items()获取dict项的类似集合的视图.然后,您可以使用<=运算符来测试一个视图是否是另一个视图的"子集":
d1.items() <= d2.items()
Run Code Online (Sandbox Code Playgroud)
在Python 2.7中,使用dict.viewitems()相同的方法:
d1.viewitems() <= d2.viewitems()
Run Code Online (Sandbox Code Playgroud)
在Python 2.6及更低版本中,您将需要一个不同的解决方案,例如使用all():
all(key in d2 and d2[key] == d1[key] for key in d1)
Run Code Online (Sandbox Code Playgroud)
git*_*rik 34
需要注意的是单元测试需要的人:assertDictContainsSubset()Python的TestCase类中也有一个方法.
然而它在3.2中被弃用,不知道为什么,也许它有一个替代品.
小智 20
对于键和值检查使用:
set(d1.items()).issubset(set(d2.items()))
如果你只需要检查键:
set(d1).issubset(set(d2))
blu*_*lub 18
为完整起见,您还可以这样做:
def is_subdict(small, big):
return dict(big, **small) == big
Run Code Online (Sandbox Code Playgroud)
但是,我没有对速度(或缺乏速度)或可读性(或缺乏速度)提出任何要求.
rob*_*ing 10
>>> 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
Run Code Online (Sandbox Code Playgroud)
背景:
>>> 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
>>>
Run Code Online (Sandbox Code Playgroud)
对于 Python 3.9,我使用的是:
def dict_contains_dict(small: dict, big: dict):
return (big | small) == big
Run Code Online (Sandbox Code Playgroud)
这是一个解决方案,它也可以正确地递归到字典中包含的列表和集合中。您也可以将它用于包含字典等的列表...
def is_subset(subset, superset):
if isinstance(subset, dict):
return all(key in superset and is_subset(val, superset[key]) for key, val in subset.items())
if isinstance(subset, list) or isinstance(subset, set):
return all(any(is_subset(subitem, superitem) for superitem in superset) for subitem in subset)
# assume that subset is a plain value if none of the above match
return subset == superset
Run Code Online (Sandbox Code Playgroud)