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