处理列表列表,查找所有具有匹配最后值的列表?

Process a list of lists, finding all lists that have matching last values?

给定一个列表列表

lol = [[0,a], [0,b],
       [1,b], [1,c],
       [2,d], [2,e],
       [2,g], [2,b],
       [3,e], [3,f]]

我想提取所有具有相同最后一个元素 (lol[n][1]) 的子列表,并得到如下所示的内容:

[0,b]
[1.b]
[2,b]
[2,e]
[3,e]

我知道给定两个列表我们可以使用交集,除了在 for each 循环中递增索引值之外,解决此类问题的正确方法是什么?

1。使用 collections.defaultdict

您可以使用 defaultdict 首先将多次出现的项目分组,然后迭代 dict.items 以获得您需要的内容。

from collections import defaultdict


lol = [[0,'a'], [0,'b'],
       [1,'b'], [1,'c'],
       [2,'d'], [2,'e'],
       [2,'g'], [2,'b'],
       [3,'e'], [3,'f']]


d = defaultdict(list)

for v,k in lol:
    d[k].append(v)

# d looks like - 
# defaultdict(list,
#             {'a': [0],
#              'b': [0, 1, 2],
#              'c': [1],
#              'd': [2],
#              'e': [2, 3],
#              'g': [2],
#              'f': [3]})
    
result = [[v,k] for k,vs in d.items() for v in vs if len(vs)>1]
print(result)
[[0, 'b'], [1, 'b'], [2, 'b'], [2, 'e'], [3, 'e']]

2。使用 pandas.duplicated

以下是如何使用 Pandas -

执行此操作
  1. 转换为 pandas 数据帧
  2. 对于关键列,找到重复项并全部保留
  3. 在忽略索引的同时转换为记录列表
import pandas as pd

df = pd.DataFrame(lol, columns=['val','key'])
dups = df[df['key'].duplicated(keep=False)]
result = list(dups.to_records(index=False))
print(result)
[(0, 'b'), (1, 'b'), (2, 'e'), (2, 'b'), (3, 'e')]

3。使用 numpy.unique

您可以使用 numpy 以矢量化方式解决此问题 -

  1. 转换为 numpy 矩阵 arr
  2. 查找唯一元素 u 及其计数 c
  3. 过滤出现不止一次的唯一元素列表dup
  4. 使用广播比较数组的第二列,并取任何超过 axis=0 的值得到一个布尔值,对于重复的行为 True
  5. 根据这个布尔值
  6. 过滤arr
import numpy as np

arr = np.array(lol)

u, c = np.unique(arr[:,1], return_counts=True)
dup = u[c > 1]

result = arr[(arr[:,1]==dup[:,None]).any(0)]
result
array([['0', 'b'],
       ['1', 'b'],
       ['2', 'e'],
       ['2', 'b'],
       ['3', 'e']], dtype='<U21')