将 defaultdict 键值与另一个 defaultdict 进行比较
compare a defaultdict key-value with another defaultdict
我有两个 defaultdict
:
defaultdict(<type 'list'>, {'a': ['OS', 'sys', 'procs'], 'b': ['OS', 'sys']})
defaultdict(<type 'list'>, {'a': ['OS', 'sys'], 'b': ['OS']})
我如何比较这两者以计算每个缺失值的数量。
例如,我应该得到两个值从键 'a'
的第二个 defaultdict 中丢失,一个从 'b'
中丢失。
您应该能够使用集合差异最有效地查找(和计算)缺失的元素。如果你很小心,你甚至可以在不向 defaultdict
添加项目的情况下执行此操作(并且不假设函数输入是 defaultdict
)。
从那里开始,只需将这些结果累积到字典中即可。
def compare_dict_of_list(d1, d2):
d = {}
for key, value in d1.items():
diff_count = len(set(value).difference(d2.get(key, [])))
d[key] = diff_count
return d
如果你只想要第二个默认字典中缺少的总数,你可以遍历第一个字典并查看设置差异以确定 A 相对于 B 多了多少东西。
如果你这样定义字典:
a = defaultdict(list, {'a': ['OS', 'sys', 'procs'], 'b': ['OS', 'sys']})
b = defaultdict(list, {'a': ['OS', 'sys'], 'b': ['OS']})
这会告诉你字典 B 中遗漏了多少:
total_missing_inB = 0
for i in a:
diff = set(a[i]) - set(b[i])
total_missing_inB += len(diff)
这会告诉你字典 A 中遗漏了多少
total_missing_inA = 0
for i in b:
diff = set(b[i]) - set(a[i])
total_missing_inA += len(diff)
在这里,我们提出了一个使用 collections.Counter
来跟踪值的替代解决方案,并且我们考虑了一些与不常见的键和值有关的边缘情况。
代码
import collections as ct
def compare_missing(d1, d2, verbose=False):
"""Return the count of missing values from dict 2 compared to dict 1."""
record = {}
for k in d1.keys() & d2.keys():
a, b = ct.Counter(d1[k]), ct.Counter(d2[k])
record[k] = a - b
if verbose: print(record)
return sum(v for c in record.values() for v in c.values())
演示
dd0 = ct.defaultdict(list, {"a": ["OS", "sys", "procs"], "b": ["OS", "sys"]})
dd1 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS"]})
compare_missing(dd0, dd1, True)
# {'a': Counter({'procs': 1}), 'b': Counter({'sys': 1})}
# 2
compare_missing(dd1, dd0, True)
# {'a': Counter(), 'b': Counter()}
# 0
详情
如果两个词典中的键不相同,compare_missing
将只迭代公共键。在下一个示例中,即使将新密钥 (c
) 添加到 dd1
,我们也会得到与上面相同的结果:
dd2 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS"], "c": ["OS"]})
compare_missing(dd0, dd2)
# 2
compare_missing(dd2, dd0)
# 0
如果找到不常见的值或重复项("admin"
和 dd3[b]
中的 "OS"
分别),这些出现次数也会被计算在内:
dd3 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS", "admin", "OS"]})
compare_missing(dd3, dd0, True)
# {'a': Counter(), 'b': Counter({'OS': 1, 'admin': 1})}
# 2
我有两个 defaultdict
:
defaultdict(<type 'list'>, {'a': ['OS', 'sys', 'procs'], 'b': ['OS', 'sys']})
defaultdict(<type 'list'>, {'a': ['OS', 'sys'], 'b': ['OS']})
我如何比较这两者以计算每个缺失值的数量。
例如,我应该得到两个值从键 'a'
的第二个 defaultdict 中丢失,一个从 'b'
中丢失。
您应该能够使用集合差异最有效地查找(和计算)缺失的元素。如果你很小心,你甚至可以在不向 defaultdict
添加项目的情况下执行此操作(并且不假设函数输入是 defaultdict
)。
从那里开始,只需将这些结果累积到字典中即可。
def compare_dict_of_list(d1, d2):
d = {}
for key, value in d1.items():
diff_count = len(set(value).difference(d2.get(key, [])))
d[key] = diff_count
return d
如果你只想要第二个默认字典中缺少的总数,你可以遍历第一个字典并查看设置差异以确定 A 相对于 B 多了多少东西。
如果你这样定义字典:
a = defaultdict(list, {'a': ['OS', 'sys', 'procs'], 'b': ['OS', 'sys']})
b = defaultdict(list, {'a': ['OS', 'sys'], 'b': ['OS']})
这会告诉你字典 B 中遗漏了多少:
total_missing_inB = 0
for i in a:
diff = set(a[i]) - set(b[i])
total_missing_inB += len(diff)
这会告诉你字典 A 中遗漏了多少
total_missing_inA = 0
for i in b:
diff = set(b[i]) - set(a[i])
total_missing_inA += len(diff)
在这里,我们提出了一个使用 collections.Counter
来跟踪值的替代解决方案,并且我们考虑了一些与不常见的键和值有关的边缘情况。
代码
import collections as ct
def compare_missing(d1, d2, verbose=False):
"""Return the count of missing values from dict 2 compared to dict 1."""
record = {}
for k in d1.keys() & d2.keys():
a, b = ct.Counter(d1[k]), ct.Counter(d2[k])
record[k] = a - b
if verbose: print(record)
return sum(v for c in record.values() for v in c.values())
演示
dd0 = ct.defaultdict(list, {"a": ["OS", "sys", "procs"], "b": ["OS", "sys"]})
dd1 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS"]})
compare_missing(dd0, dd1, True)
# {'a': Counter({'procs': 1}), 'b': Counter({'sys': 1})}
# 2
compare_missing(dd1, dd0, True)
# {'a': Counter(), 'b': Counter()}
# 0
详情
如果两个词典中的键不相同,compare_missing
将只迭代公共键。在下一个示例中,即使将新密钥 (c
) 添加到 dd1
,我们也会得到与上面相同的结果:
dd2 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS"], "c": ["OS"]})
compare_missing(dd0, dd2)
# 2
compare_missing(dd2, dd0)
# 0
如果找到不常见的值或重复项("admin"
和 dd3[b]
中的 "OS"
分别),这些出现次数也会被计算在内:
dd3 = ct.defaultdict(list, {"a": ["OS", "sys"], "b": ["OS", "admin", "OS"]})
compare_missing(dd3, dd0, True)
# {'a': Counter(), 'b': Counter({'OS': 1, 'admin': 1})}
# 2