我有两个字典列表:
dict_list1 = [{'k1':1, 'k2':2}, {'k1':3, 'k2':4}]
dict_list2 = [{'k1':1, 'k2':2, 'k3':10}, {'k1':3, 'k2':4, 'k3':10}]
现在对于 dict_list1 中的每个 dict_x,我想知道 dict_list2 上是否有一个 dict_y 包含来自 dict_x 的每个键和值。
除此之外我想不出另一种方法:
for dict_x in dict_list1:
for dict_y in dict_list2:
count = len(dict_x)
for key, val in dict_x.items():
if key in dict_y and dict_y[key] == val:
count -= 1
if count == 0:
print('YAY')
break
请您参考如下方法:
dict View 可以通过不等运算符执行快速“是子集”测试。所以:
if dict_x.items() <= dict_y.items(): # Use .viewitems() instead of .items() on Python 2.7
仅当 dict_x 中的每个键/值对也出现在 dict_y 中时才会返回 true。
这不会改变 big-O 性能,但它确实使代码更简洁:
for dict_x in dict_list1:
for dict_y in dict_list2:
if dict_x.items() <= dict_y.items():
print('YAY')
break
请注意,创建 View 会花费一些(这只是固定成本,不依赖于 dict 大小),因此如果性能很重要,那么缓存 View 可能是值得的;为 dict_list1 这样做是免费的:
for dict_x in dict_list1:
dict_x_view = dict_x.items()
for dict_y in dict_list2:
if dict_x_view <= dict_y.items():
print('YAY')
break
但是需要一些急切的转换来缓存两者:
# Convert all of dict_list2 to views up front; costs a little if
# not all views end up being tested (we always break before finishing)
# but usually saves some work at the cost of a tiny amount of memory
dict_list2_views = [x.items() for x in dict_list2]
for dict_x in dict_list1:
dict_x_view = dict_x.items()
for dict_y_view in dict_list2_views:
if dict_x_view <= dict_y_view:
print('YAY')
break
您还可以使用 any 来折叠循环(这消除了 break 的需要,因为 any 短路),所以第一个 (最简单的)检查可能变成:
for dict_x in dict_list1:
if any(dict_x.items() <= dict_y.items() for dict_y in dict_list2):
print('YAY')
这可以进一步折叠为导致各种匹配的单个列表理解,但此时代码将变得非常局促/丑陋:
for _ in (dict_x in dict_list1 if any(dict_x.items() <= dict_y.items() for dict_y in dict_list2)):
print('YAY')
虽然不知道您真正要做什么(而不是仅仅打印 YAY),但这变得有点毫无意义。
