如何检查多维字典中是否存在指定主机与IP的关联记录?
用Lambda搞定IP-主机记录的去重添加问题
嘿,我明白你现在的需求:手里有个IP对应主机记录列表的字典,要加新记录但得先去重——而且同一IP下,只要已有相同host且不是CNAME的记录,就不能重复加,还想用上lambda来定位目标记录对吧?
第一步:用Lambda+next()精准找目标记录
要快速排查是否存在符合条件的重复记录,咱们可以把lambda的逻辑和next()函数结合起来用,比直接写遍历循环简洁多了。
举个实际例子,假设你要把www.abc.com加到10.0.0.1对应的列表里:
# 先确保目标IP在字典里有对应的列表,没有就自动创建一个空列表 items.setdefault('10.0.0.1', []) # 用lambda逻辑筛选:找host匹配且record_type不是cname的记录 existing_record = next( (item for item in items['10.0.0.1'] if item['host'] == 'www.abc.com' and item['record_type'] != 'cname'), None # 找不到符合条件的就返回None )
这里的生成器表达式里就藏着lambda的核心逻辑——咱们直接根据字段内容做匹配,不用管对象的内存地址,完美解决你说的不能用in判断的问题。
第二步:判断是否添加新记录
拿到existing_record之后,逻辑就很清晰了:如果是None,说明没有重复的非CNAME记录,直接添加就行;反之就跳过。
# 假设你要添加的新记录长这样 new_record = { 'host': 'www.abc.com', 'record_type': 'a', # 其他需要的字段... } if not existing_record: items['10.0.0.1'].append(new_record) print("记录成功添加啦!") else: print("这个主机已经有非CNAME记录了,不用重复加~")
为啥不用in?
你说的没错,直接克隆对象用in判断根本行不通——因为字典是可变对象,in只会检查内存地址是否一致,不会对比内容。而咱们用的lambda+生成器方式,是实打实对比字段值,精准度拉满。
封装成函数更方便(可选)
如果要多次添加记录,把逻辑封装成函数会更顺手:
def add_host_record(items, target_ip, new_record): # 确保IP对应的列表存在 items.setdefault(target_ip, []) target_host = new_record['host'] # 查找重复的非CNAME记录 existing = next( (item for item in items[target_ip] if item['host'] == target_host and item['record_type'] != 'cname'), None ) if not existing: items[target_ip].append(new_record) return True # 返回True表示添加成功 return False # 返回False表示已有重复记录 # 测试一下 items = { '10.0.0.1': [ { 'host': 'abc.com', 'record_type': 'a' }, { 'host': 'www.abc.com', 'record_type': 'cname' } ] } new_record = {'host': 'www.abc.com', 'record_type': 'a'} add_host_record(items, '10.0.0.1', new_record) print(items)
运行这个代码,因为原来的www.abc.com是CNAME记录,所以新的A记录会被成功添加;如果之前已经有相同host的非CNAME记录,就会直接跳过。
内容的提问来源于stack exchange,提问作者e-info128
相关产品推荐
相关产品推荐

