嵌套循环中if!=逻辑异常及Python列表差异匹配实现咨询
嵌套循环中if/else逻辑异常的原因及解决方法
问题代码
test1 = [{'DataTime': '03.02.2023', 'id': '112233', 'idd': '0000123'}, {'DataTime': '03.02.2023', 'id': '112234', 'idd': '0000124'}, {'DataTime': '03.02.2023', 'id': '112235', 'idd': '0000125'}, {'DataTime': '03.02.2023', 'id': '112236', 'idd': '0000126'} ] test2 = [ {'Data': ['03.02.2023'], 'id': ['112233'], 'idd': ['333444']}, {'Data': ['03.02.2023'], 'id': ['112255'], 'idd': ['555535']}, {'Data': ['03.02.2023'], 'id': ['112288'], 'idd': ['223455']} ] for a in test1: for b in test2: if b['id'][0] == a['id']: print(a)
问题现象
使用if b['id'][0] == a['id']时,能正确输出test1中与test2匹配的条目;但改用if b['id'][0] != a['id']时,会重复输出test1的所有内容,而非仅输出test1中与test2不匹配的条目(id为112234、112235、112236的条目)。
原因分析
嵌套循环的逻辑是每个test1的条目a会和test2里的所有b逐一比较:
- 当用
==时,只要找到一个匹配的b就打印一次a,而test1中只有id=112233的条目能找到匹配项,所以只打印一次。 - 当用
!=时,每遇到一个不匹配的b就打印一次a。比如test1中id=112234的条目,会和test2的3个b比较,其中2个b的id和它不匹配,所以会被打印2次;同理其他条目也会因为多次不匹配而重复打印,最终出现“重复输出所有内容”的现象。
这种写法的核心问题是:你想判断的是a是否在test2中完全没有匹配项,但实际写的是a和当前b是否不匹配,两者逻辑完全不同。
正确实现方法
方法1:用集合预处理(高效推荐)
先提取test2中所有的id到集合,再遍历test1判断id是否不在集合中。集合的查找效率是O(1),比嵌套循环的O(n*m)更高效。
test1 = [{'DataTime': '03.02.2023', 'id': '112233', 'idd': '0000123'}, {'DataTime': '03.02.2023', 'id': '112234', 'idd': '0000124'}, {'DataTime': '03.02.2023', 'id': '112235', 'idd': '0000125'}, {'DataTime': '03.02.2023', 'id': '112236', 'idd': '0000126'} ] test2 = [ {'Data': ['03.02.2023'], 'id': ['112233'], 'idd': ['333444']}, {'Data': ['03.02.2023'], 'id': ['112255'], 'idd': ['555535']}, {'Data': ['03.02.2023'], 'id': ['112288'], 'idd': ['223455']} ] # 提取test2中所有id到集合 test2_id_set = {item['id'][0] for item in test2} # 筛选test1中不在test2里的条目 for entry in test1: if entry['id'] not in test2_id_set: print(entry)
方法2:嵌套循环加标记变量
如果一定要用嵌套循环,可以用一个标记变量记录是否找到匹配项,遍历完test2后再判断是否打印:
for a in test1: has_match = False for b in test2: if b['id'][0] == a['id']: has_match = True break # 找到匹配项就跳出内层循环,减少不必要的比较 if not has_match: print(a)
内容的提问来源于stack exchange,提问作者Father
相关产品推荐
相关产品推荐

