Skip to main content
 首页 » 编程设计

Python 比较标记化列表

2025年05月04日14三少

我需要最快的解决方案来解决这个问题,因为它将应用于一个巨大的数据集:

鉴于此主列表:

m=['abc','bcd','cde','def'] 

...以及这个列表的引用列表:

r=[['abc','def'],['bcd','cde'],['abc','def','bcd']] 

我想将 r 中的每个列表与主列表 (m) 进行比较,并生成一个新的列表列表。这个新对象将根据 m 中的顺序为匹配项设置 1,不匹配项设置为 0。因此新对象(列表的列表)将始终具有与 m 相同长度的列表。 这是我基于上面的 m 和 r 的期望:

[[1,0,0,1],[0,1,1,0],[1,1,0,1]] 

因为 r 的第一个元素是 ['abc','def'] 并且有匹配 使用 m 的第 1 个和第 4 个元素,结果是 [1,0,0,1]。

到目前为止,这是我的方法(可能太慢并且缺少零):

output=[] 
for i in r: 
    output.append([1 for x in m if x in i]) 

导致:

[[1, 1], [1, 1], [1, 1, 1]] 

提前致谢!

请您参考如下方法:

您可以像这样使用嵌套列表理解:

>>> m = ['abc','bcd','cde','def'] 
>>> r = [['abc','def'],['bcd','cde'],['abc','def','bcd']] 
>>> [[1 if mx in rx else 0 for mx in m] for rx in r] 
[[1, 0, 0, 1], [0, 1, 1, 0], [1, 1, 0, 1]] 

此外,您可以使用 int(...) 缩短 1 if ... else 0,并且可以转换 r< 的子列表 到 set,以便单个 mx in rx 查找速度更快。

>>> [[int(mx in rx) for mx in m] for rx in r] 
[[1, 0, 0, 1], [0, 1, 1, 0], [1, 1, 0, 1]] 
>>> [[int(mx in rx) for mx in m] for rx in map(set, r)] 
[[1, 0, 0, 1], [0, 1, 1, 0], [1, 1, 0, 1]] 

虽然 int(...) 比 1 if ... else 0 短一点,但它似乎也更慢,因此您可能不应该使用那。在重复查找之前将 r 的子列表转换为 set 应该会加快较长列表的速度,但对于非常短的示例列表,它实际上比天真的方法慢.

>>> %timeit [[1 if mx in rx else 0 for mx in m] for rx in r] 
100000 loops, best of 3: 4.74 µs per loop 
>>> %timeit [[int(mx in rx) for mx in m] for rx in r] 
100000 loops, best of 3: 8.07 µs per loop 
>>> %timeit [[1 if mx in rx else 0 for mx in m] for rx in map(set, r)] 
100000 loops, best of 3: 5.82 µs per loop 

对于更长的列表,使用 set 会变得更快,正如预期的那样:

>>> m = [random.randint(1, 100) for _ in range(50)] 
>>> r = [[random.randint(1,100) for _ in range(10)] for _ in range(20)] 
>>> %timeit [[1 if mx in rx else 0 for mx in m] for rx in r] 
1000 loops, best of 3: 412 µs per loop 
>>> %timeit [[1 if mx in rx else 0 for mx in m] for rx in map(set, r)] 
10000 loops, best of 3: 208 µs per loop