【问题标题】:Compare two lists A, B in Python find all elements in A which correspond to the same number in B比较Python中的两个列表A,B找到A中与B中相同数字对应的所有元素
【发布时间】:2017-06-19 00:32:29
【问题描述】:

我想比较两个 Python 列表,“A”和“B”,以便我可以找到 A 中的所有元素,它们对应于 B 中的相同数字强>。我想为B 中的每个数字 执行此操作。例如,如果

A = [5, 7, 9, 12, 8, 16, 25]
B = [2, 1, 3, 2, 3, 1, 4]

我想买

[7,16] corresponding to the number 1 of listB
[5, 12] corresponding to the number 2 of listB
[9, 8] corresponding to the number 3 of listB
[25] corresponding to the number 4 of listB

A 和 B 将始终具有相同的长度。

【问题讨论】:

  • 不明白这里的逻辑...能否请您提供更多细节? [7,16] corresponding to the number 1 of listB ... 为什么?
  • 哦,好吧,我明白了:在列表 B 中,1 在第 2 和第 6 位,而列表 A 中这些位置的数字是 7 和 16。

标签: python list


【解决方案1】:

您可以使用zip 创建由两个列表中的一个元素组成的元组,然后对它们进行排序,最后按来自B 的值对它们进行分组:

>>> from itertools import groupby
>>> A = [5, 7, 9, 12, 8, 16, 25]
>>> B = [2, 1, 3, 2, 3, 1, 4]
>>> for k, g in groupby(sorted(zip(B,A)), key=lambda x: x[0]):
...     print('{} corresponds to {}'.format([x[1] for x in g], k))
... 
[7, 16] corresponds to 1
[5, 12] corresponds to 2
[8, 9] corresponds to 3
[25] corresponds to 4

在上面的zip(B, A) 返回可迭代的元组,其中每个元组都有来自BA 的元素:

>>> list(zip(B,A))
[(2, 5), (1, 7), (3, 9), (2, 12), (3, 8), (1, 16), (4, 25)]

然后对上面的结果进行排序,以便B 中具有相同值的所有元组彼此相邻:

>>> sorted(zip(B,A))
[(1, 7), (1, 16), (2, 5), (2, 12), (3, 8), (3, 9), (4, 25)]

排序结果被传递给groupby,它根据键函数返回的值对元组进行分组,在本例中是元组中的第一项。结果可迭代 (key, group) 元组,其中 group 可迭代元素:

>>> [(k, list(g)) for k, g in groupby(sorted(zip(B,A)), key=lambda x: x[0])]
[(1, [(1, 7), (1, 16)]), (2, [(2, 5), (2, 12)]), (3, [(3, 8), (3, 9)]), (4, [(4, 25)])]

【讨论】:

  • 非常优雅的响应
【解决方案2】:

我认为您可以使用此代码:

A = [5, 7, 9, 12, 8, 16, 25]
B = [2, 1, 3, 2, 3, 1, 4]

d = {}

for a, b in zip(A, B):
    d.setdefault(b, [])
    d[b].append(a)

for k, v in sorted(d.items()):
    print('{} corresponds {}'.format(v, k))

字典的每个键都是B的一个元素,其关联的值就是你想要的列表。

【讨论】:

    【解决方案3】:

    试试这个方法。

    unique = set(B)    # Creates a set of unique entries in B
    for u in unique:
        # Find indices of unique entry u
        indices = [i for i, x in enumerate(B) if x == u]
    
        # Pull out these indices in A
        corrEntry = [A[i] for i in indices]  
    
        # Do something with the data, in this case print what OP wants
        print('{} corresponds to the number {} of list B'.format(corrEntry , B[indices[0]]))
    

    它使用set 函数在B 中查找唯一条目。 然后我们遍历这些独特的条目。第一个列表推导(用于indices)查找 B 中与此唯一条目匹配的条目的索引。第二个保存这些索引的 A 中的值。

    【讨论】:

    • 您的代码实际上不起作用。我已经运行了它,这不是用户要求的。 print(indices, correspondingEntries),我收到了[1, 5] [7, 16] [0, 3] [5, 12] [2, 4] [9, 8] [6] [25]
    • 只需打印correspondingEntriesindices 什么都不需要,是个中介
    • 重点是@SiddTheKid 会想要这个条目相同的数字,这是问题的重点
    【解决方案4】:

    使用collections.defaultdict的替代方法:

    import collections as ct
    
    dd = ct.defaultdict(list)
    for a, b in zip(A, B):
        dd[b].append(a)
    
    dd
    # defaultdict(list, {1: [7, 16], 2: [5, 12], 3: [9, 8], 4: [25]})
    

    打印结果示例:

    for k, v in sorted(dd.items()):
        print("{} corresponding to the number {} of listB".format(v, k))
    
    # [7, 16] corresponding to the number 1 of listB
    # [5, 12] corresponding to the number 2 of listB
    # [9, 8] corresponding to the number 3 of listB
    # [25] corresponding to the number 4 of listB
    

    【讨论】:

      【解决方案5】:
      A = [5, 7, 9, 12, 8, 16, 25]
      B = [2, 1, 3, 2, 3, 1, 4]
      

      创建一个以两个列表(AB)和一个数字(n)作为参数的特定函数。选择A 中与B 中等同于n 的项目具有相同列表位置的所有项目。 zip 用于将来自AB 的项目与相同的列表位置配对。此函数使用列表推导从 A 中选择项目。

      >>> def f(A, B, n):
          return [a for a, b in zip(A,B) if b == n]
      
      >>> f(A, B, 2)
      [5, 12]
      >>> 
      

      可以在没有列表理解的情况下编写函数:

      def g(A, B, n):
          result = []
          for a, b in zip(A, B):
              if b == n:
                  result.append(a)
          return result
      

      使用 fuctools.partial 可以修复列表参数:

      import functools
      f_AB = functools.partial(f, A, B)
      

      那么它可以这样使用:

      >>> f_AB(3)
      [9, 8]
      
      >>> numbers = [3, 4, 2]
      >>> for n in numbers:
          print (n, f_AB(n))
      
      (3, [9, 8])
      (4, [25])
      (2, [5, 12])
      >>>
      

      【讨论】:

      • 一些解释可能会有所帮助。
      • thnx,@Pavlo - 我有点懒了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      相关资源
      最近更新 更多