基于长度与交集筛选得分为0的列表元素的Python优化方法问询
优化列表筛选逻辑的Python实现方案探讨
问题背景
首先给出初始的两个列表定义:
l1 = [['a', 'b', 'c'], ['a', 'd', 'c'], ['a', 'e'], ['a', 'd', 'c'], ['a', 'f', 'c'], ['a', 'e'], ['p', 'q', 'r']] l2 = [1, 1, 1, 2, 0, 0, 0]
其中l1是嵌套列表结构,l2是与l1元素一一对应的得分列表。
筛选需求
我们需要从l1中筛选出所有对应l2得分为0的列表,筛选规则如下:
- 保留与其他得分为0的列表完全无交集的列表;
- 若存在交集的列表组,保留其中长度最短的列表(当长度相等时,该组内的所有列表都保留)。
示例说明
若有得分为0的列表
[1, 2, 3]、[2, 3]、[5, 7],则最终选择[5, 7](与其他列表无交集)和[2, 3](与[1, 2, 3]有交集但长度更短)。
当前实现代码
基础版本
这是最初实现筛选逻辑的代码:
import itertools l1 = [['a', 'b', 'c'], ['a', 'd', 'c'], ['a', 'e'], ['a', 'd', 'c'], ['a', 'f', 'c'], ['a', 'e'], ['p', 'q', 'r']] l2 = [1, 1, 1, 2, 0, 0, 0] l = [x for x, y in zip(l1, l2) if y == 0] lx = [(x, y) for x, y in zip(l1, l2) if y > 0] c = list(itertools.combinations(l, 2)) un_usable = [] usable = [] for i, j in c: intersection = len(set(i).intersection(set(j))) if intersection > 0: if len(i) < len(j): usable.append(i) un_usable.append(j) else: usable.append(j) un_usable.append(i) for i, j in c: intersection = len(set(i).intersection(set(j))) if intersection == 0: if i not in un_usable and i not in usable: usable.append(i) if j not in un_usable and j not in usable: usable.append(j) final = lx + [(x, 0) for x in usable]
运行后得到预期结果:
[(['a', 'b', 'c'], 1), (['a', 'd', 'c'], 1), (['a', 'e'], 1), (['a', 'd', 'c'], 2), (['a', 'e'], 0), (['p', 'q', 'r'], 0)]
补充长度相等处理的版本
为了兼容长度相等的列表都保留的场景,对代码做了补充优化:
import itertools l1 = [['a', 'b', 'c'], ['a', 'd', 'c'], ['a', 'e'], ['a', 'd', 'c'], ['a', 'f', 'c'], ['a', 'e'], ['p', 'q', 'r'], ['a', 'k']] l2 = [1, 1, 1, 2, 0, 0, 0, 0] l = [x for x, y in zip(l1, l2) if y == 0] lx = [(x, y) for x, y in zip(l1, l2) if y > 0] c = list(itertools.combinations(l, 2)) un_usable = [] usable = [] for i, j in c: intersection = len(set(i).intersection(set(j))) if intersection > 0: if len(i) < len(j): usable.append(i) un_usable.append(j) elif len(i) == len(j): usable.append(i) usable.append(j) else: usable.append(j) un_usable.append(i) # 对usable和un_usable去重 usable = [list(x) for x in set(tuple(x) for x in usable)] un_usable = [list(x) for x in set(tuple(x) for x in un_usable)] for i, j in c: intersection = len(set(i).intersection(set(j))) if intersection == 0: if i not in un_usable and i not in usable: usable.append(i) if j not in un_usable and j not in usable: usable.append(j) final = lx + [(x, 0) for x in usable]
提问
是否存在更高效、更符合Python风格的实现方式?
内容的提问来源于stack exchange,提问作者Abhishek Thakur
相关产品推荐
相关产品推荐

