Python 根据长度和交集从列表列表中选择元素
我有两份清单,如上所述Python 根据长度和交集从列表列表中选择元素,python,list,Python,List,我有两份清单,如上所述l1是一个列表列表,l2是另一个带有某种分数的列表 问题:对于得分为0(来自l2)的l1中的所有列表,找到那些完全不同或长度最小的列表 例如:如果我的列表[1,2,3],[2,3],[5,7]的分数都为0,我将选择[5,7],因为这些元素不存在于任何其他列表中,[2,3],因为它与[1,2,3]相交,但长度较小 我现在是如何做到这一点的: l1 = [['a', 'b', 'c'], ['a', 'd', 'c'], ['a', 'e'],
l1
是一个列表列表,l2
是另一个带有某种分数的列表
问题:对于得分为0
(来自l2
)的l1
中的所有列表,找到那些完全不同或长度最小的列表
例如:如果我的列表[1,2,3]
,[2,3]
,[5,7]
的分数都为0,我将选择[5,7]
,因为这些元素不存在于任何其他列表中,[2,3]
,因为它与[1,2,3]
相交,但长度较小
我现在是如何做到这一点的:
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]
这是必需的结果
编辑:要处理相等的长度,请执行以下操作:
[(['a', 'b', 'c'], 1),
(['a', 'd', 'c'], 1),
(['a', 'e'], 1),
(['a', 'd', 'c'], 2),
(['a', 'e'], 0),
(['p', 'q', 'r'], 0)]
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代表x,y在zip(l1,l2)中,如果y==0]
lx=[(x,y)表示zip(l1,l2)中的x,y,如果y>0]
c=列表(itertools.组合(l,2))
un_可用=[]
可用=[]
对于c中的i,j:
交叉点=长度(集合(i).交叉点(集合(j)))
如果交点>0:
如果len(i)
有没有更好的、更快的、类似蟒蛇的方法来达到同样的效果 假设我正确理解了所有内容,下面是一个O(N)双通道算法 步骤:
def-select_-lsts(lsts,分数):
#选出零分名单
z_lsts=[lst代表lst,如果得分=0,则在zip中得分(lst,得分)
#跟踪元素所在列表的最短长度
len_shortest=dict()
对于z_lst中的lst:
ln=len(lst)
对于lst中的c:
len_shortest[c]=min(ln,len_shortest.get(c,float('inf'))
#检查列表是否为每个字符的最小长度
对于z_lst中的lst:
len_lst=len(lst)
如果有(长度最短[c]<长度为c的长度):
持续
产量lst
代码改进属于我知道的领域,但我也在寻找更好的算法来实现这一点。我发布的代码是:“你做了什么?”:)如果两个列表共享一些数字,如[1,2]
和[1,3]
,该怎么办?它们都会包含在输出中吗?为什么输出中不包括['a',f',c']
?a,f,c
与a,e
共享a
,因为后者的长度较小,所以被选中。您提到的案例应该同时包含[1,2]
和[2,3]
,可能是1000秒。没有这样的限制。
[(['a', 'b', 'c'], 1),
(['a', 'd', 'c'], 1),
(['a', 'e'], 1),
(['a', 'd', 'c'], 2),
(['a', 'e'], 0),
(['p', 'q', 'r'], 0)]
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 = [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]
def select_lsts(lsts, scores):
# pick out zero score lists
z_lsts = [lst for lst, score in zip(lsts, scores) if score == 0]
# keep track of the shortest length of any list in which an element occurs
len_shortest = dict()
for lst in z_lsts:
ln = len(lst)
for c in lst:
len_shortest[c] = min(ln, len_shortest.get(c, float('inf')))
# check if the list is of minimum length for each of its chars
for lst in z_lsts:
len_lst = len(lst)
if any(len_shortest[c] < len_lst for c in lst):
continue
yield lst