简体   繁体   English

Python:一个列表中两个位置之间的差异取决于另一个列表的规则集

[英]Python: Difference between two positions in one list depending on rule set for another list

Consider two lists of identical length:考虑两个长度相同的列表:

  • t is a list of irregular-intervals of times in seconds, arranged chronologically t是以秒为单位的不规则时间间隔列表,按时间顺序排列
  • pt is a list of sequences of numbers 1,2,3 wsuch that a 1 is followed by a consecutive string of 2's, then followed by a 3. pt是数字 1,2,3 的序列列表,其中 1 后跟连续的 2 字符串,然后是 3。
    • 1 = start of event, 2 = continuation of event, 3 = end of event 1 = 事件开始,2 = 事件继续,3 = 事件结束
    • This means that for a single event, the sequence begins with a single 1, is followed by a consecutive string of 2s (how many times it repeats will vary), and finally ends in a single 3.这意味着对于单个事件,序列以单个 1 开始,然后是连续的 2 字符串(重复的次数会有所不同),最后以单个 3 结束。
    • There is more than 1 event contained in this vector此向量中包含 1 个以上的事件

For example, the input could look like:例如,输入可能如下所示:

#    |--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] 

Is there a 1-liner that doesn't involve multiple nested loops that we could use that would calculate the difference in time values in t for each event sequence in pt ?是否有一个 1-liner 不涉及多个嵌套循环,我们可以使用它来计算pt每个事件序列在t中的时间值差异?

For example, the desired output for the above inputs would be a list of length 3 (because there are 3 events) where the output is例如,上述输入所需的输出将是长度为 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]

using pure python :使用纯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]

using more_itertools.chunked() :使用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]

explanation解释

If you look close, we see this list comprehension occurring multiple times.如果您仔细观察,我们会看到多次出现此列表推导式。 This is the center of the solution!这是解决方案的中心!

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

So, what's going on?发生什么了?

Using the zip function, we make a list of the paired elements, and if the x element (1st list element pair) is either 1 or 3 we add it to the list.使用zip函数,我们创建一个配对元素的列表,如果 x 元素(第一个列表元素对)是 1 或 3,我们将它添加到列表中。

This gives us a list of the differences we need to find.这为我们提供了需要查找的差异列表。

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

Now comes the second part, getting the differences from these.现在是第二部分,从中获取差异。 We essentially need to make pairs from this, the method I'm going to use here is chunking.我们基本上需要从中进行配对,我将在这里使用的方法是分块。 The pure python way to partition a list into chunks is as follows:将列表分成块的纯 python 方法如下:

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

using this we could partition the [1, 14, 17, 37, 32, 38] list to:使用这个我们可以将[1, 14, 17, 37, 32, 38]列表划分为:

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

but it's far simpler to just get the differences immediately!但立即获得差异要简单得多!

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

This seems to work这似乎有效

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] 

st = 0
lst = []
for x in zip(pt,t):
   if x[0] == 1: st = x[1]
   if x[0] == 3: 
      d = x[1] - st
      lst.append(d)

print(lst)

Output输出

[13, 20, 6]

Code:代码:

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] 

events_t =[]
arr = []
for pt_ele, t_ele in zip(pt, t):
    arr.append(t_ele)
    if pt_ele == 3:
        events_t.append(arr)
        arr = []
print(events_t)
res = [i[-1] - i[0] for i in events_t]
print(res)

Output:输出:

[[1, 10, 13, 14], [17, 20, 21, 25, 37], [32, 33, 38]]
[13, 20, 6]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM