代码之家  ›  专栏  ›  技术社区  ›  송준석

是否可以提取包含重复值的交叉点列表?

  •  0
  • 송준석  · 技术社区  · 6 年前

    我想得到一个列表的交集,在这里不消除重复。 我希望这种方法是一种不使用循环的快速方法。 下面是我的尝试,但是这个方法失败了,因为重复项被删除了。

    a = ['a','b','c','f']
    b = ['a','b','b','o','k']
    
    tmp = list(set(a) & set(b))
    >>>tmp
    >>>['b','a']
    

    我希望结果是 ['a', 'b', 'b']

    在这种方法中, 'a' 是一个固定值 'b' 是一个变量值。

    “a” 价值来自 .

    有没有一种方法可以提取不删除重复值的交叉值列表?

    1 回复  |  直到 6 年前
        1
  •  2
  •   6502    6 年前

    解决办法可能是

    good = set(a)
    result = [x for x in b if x in good]
    

    这里有两个回路;一是建筑环线的设置 set (这是用C实现的,比用Python做的任何事情都快一百倍)另一个是理解和在解释器中运行。 第一个循环是为了避免线性搜索 a 对于每个元素 b (如果 变得很大(这可能是一个严重的问题)。

    注意,使用 filter 循环在C中,对于每个元素,它必须返回到解释器来调用过滤函数。

    对于在中连续的重复项 b 就像你的例子一样)

    good = set(a)
    res = []
    i = 0
    while i < len(b):
        x = b[i]
        if x in good:
            while i < len(b) and b[i] == x:  # is?
                res.append(x)
                i += 1
        else:
            i += 1
    

        2
  •  1
  •   EliadL ThiefMaster    6 年前

    如果你坚持不使用 for 这样就行了:

    >>> list(filter(a.__contains__, b))
    ['a', 'b', 'b']
    

    __contains__ 据我所知,这不是推荐的做法,因此请考虑以下内容:

    >>> list(filter(lambda x: x in a, b))
    ['a', 'b', 'b']
    

    如果你想改善在 a O(n) set 首先:

    >>> a_set = set(a)
    >>> list(filter(lambda x: x in a_set, b))
    ['a', 'b', 'b']
    
        3
  •  1
  •   Justice_Lords    6 年前
    >>a = ['a','b','c','f']
    >>b = ['a','b','b','o','k']
    >>items = set(a)
    >>found = [i for i in b if i in items]
    >>items
    {'f', 'a', 'c', 'b'}
    >>found
    ['a', 'b', 'b']
    

    这应该是你的工作。

        4
  •  1
  •   iGian    6 年前

    我猜这并不比一个循环快,最后你可能仍然需要一个循环来提取结果。不管怎样。。。

    from collections import Counter
    
    a = ['a','a','b','c','f']
    b = ['a','b','b','o','k']
    
    count_b = Counter(b)
    count_ab = Counter(set(b)-set(a))
    count_b - count_ab
    
    #=> Counter({'a': 1, 'b': 2})
    


    我是说,如果 res 保存结果时,您需要:
    [ val for sublist in [ [s] * n for s, n in res.items() ] for val in sublist ]
    #=> ['a', 'b', 'b']
    
        5
  •  1
  •   Ṃųỻịgǻňạcểơửṩ    6 年前

    不清楚在执行包含重复元素的列表的交集时如何处理重复项,因为您只给出了一个测试用例及其预期结果,并且没有解释重复处理。

    根据目前保存副本的工作方式,常见的元素有 'a' 'b' “a” “b” “a” 在两个列表上都发生一次 b ,但是 在上发生两次 b 多样性。

    答案是 . 但是,可以隐式地调用循环—尽管您希望代码不显式地使用任何循环语句。然而,这个算法总是迭代的。

    第一步: Intersect 不包含重复项的(您已经这样做了)。转换为列表以保持索引。

    第二步: IntersectD . 创建新变量 Freq 它使用 count 横断 频率 Intersect[k] 根据其相应的 Freq[k] .

    a = ['a','b','c','1','1','1','1','2','3','o']
    b = ['a','b','b','o','1','o','1']
    c = ['a','a','a','b','1','2']
    
    intersect = list(set(a) & set(b) & set(c)) # 3-set case
    intersectD = []
    
    for k in range(len(intersect)):
      cmn = intersect[k]
      freq = max(a.count(cmn), b.count(cmn), c.count(cmn)) # 3-set case
      for i in range(freq): # Can be done with itertools
        intersectD.append(cmn)
    
    >>> intersectD
    >>> ['b', 'b', 'a', 'a', 'a', '1', '1', '1', '1']
    

    freq 频率 How can I count the occurrences of a list item? .

    推荐文章