首页 > 解决方案 > Python:一个列表中两个位置之间的差异取决于另一个列表的规则集

问题描述

考虑两个相同长度的列表:

例如,输入可能如下所示:

#    |--Event #1-|   |---Event #2----|   |Event #3 | 
pt = [1, 2,  2,  3,  1,  2,  2,  2,  3,  1,  2,  3 ]
t =  [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38] 

是否有一个不涉及多个嵌套循环的 1-liner,我们可以使用它来计算t每个事件序列的时间值差异pt

例如,上述输入的所需输出将是长度为 3 的列表(因为有 3 个事件),其中输出为

Output: [13, 20, 6]

### Explanation:
# 13 = 14-1  = t[position where pt shows first 3]  - t[position where pt shows first 1]
# 20 = 37-17 = t[position where pt shows second 3] - t[position where pt shows second 1]
# 6  = 38-32 = t[position where pt shows third 3]  - t[position where pt shows third 1]

标签: pythonlist

解决方案


使用纯python

pt = [1, 2,  2,  3,  1,  2,  2,  2,  3,  1,  2,  3 ]
t =  [1, 10, 13, 14, 17, 20, 21, 25, 37, 32, 33, 38]

l = [y for x, y in zip(pt,t) if x in [1,3]]

print([l[i:i+2][1] - l[i:i+2][0] for i in range(0, len(l), 2)])
[13, 20, 6]

使用more_itertools.chunked()

from more_itertools import chunked

print([y-x for x,y in chunked([y for x, y in zip(pt,t) if x in [1,3]], 2)])
[13, 20, 6]

解释

如果您仔细观察,我们会看到此列表理解多次出现。这是解决方案的中心!

[y for x, y in zip(pt,t) if x in [1,3]]

发生什么了?

使用该zip函数,我们创建一个成对元素的列表,如果 x 元素(第一个列表元素对)是 1 或 3,我们将其添加到列表中。

这为我们提供了需要查找的差异列表。

#|---|  |----|  |----|
[1, 14, 17, 37, 32, 38]

现在是第二部分,从中获得差异。我们本质上需要从中进行配对,我将在这里使用的方法是分块。将列表划分为块的纯python方法如下:

#given a list l
chunklen = 2 
[l[i:i+chunklen] for i in range(0, len(l), chunklen)]

使用它,我们可以将[1, 14, 17, 37, 32, 38]列表划分为:

[[1, 14], [17, 37], [32, 38]]

但是立即获得差异要简单得多!

l[i:i+chunklen][1]-l[i:i+chunklen][0]
#given l[i:i+chunklen] as [1, 14] this would return 14-1 i.e. 13

推荐阅读