Python: How to align two lists using start/end timestamps in the item

205 views Asked by At

I have two lists, each sorted by start_time and that the end_time does not overlap with other items:

# (word, start_time, end_time)
words = [('i', 5.12, 5.23),
         ('like', 5.24, 5.36),
         ('you', 5.37, 5.71),
         ('really', 7.21, 7.51),
         ('yes', 8.32, 8.54)]

# (speaker, start_time, end_time)
segments = [('spk1', 0.0, 1.25),
            ('spk2', 4.75, 6.25),
            ('spk1', 6.75, 7.75),
            ('spk2', 8.25, 9.25)]

I want to group the items in words that fall within the start_time and end_time of each item in segments and produce something like this:

res = [('i', 'like', 'you'),
       ('really'),
       ('yes')]

such that each item in res contains all the items of words with start_time and end_time falling between the start_time and end_time of the corresponding item in segments.

2

There are 2 answers

0
Simon On

single loop should be fast.

res = [                                         # initialize beforehand
    [
        seg[0], 
        seg[1], 
        seg[2], 
        round(seg[2] - seg[1], 2), 
        '',                                     # with empty speech
     ] for seg in segments
        ]
i = 0                                           # index of res
for word in words:                              # for each row of word
    if word[1] >= res[i][2]:                    # next speaker?
        i = i + 1                               # next res index
    if res[i][4]:                               # not empty speech
        res[i][4] = res[i][4] + ' ' + word[0]   # space in between
    else:                                       # empty speech
        res[i][4] = word[0]                     # initialize it

Happy Sunday!

0
Hackore On

I came up with this solution while I was typing out the question. I guess stackoverflow is a good rubber duck. But I would love to hear if there is a more time-efficient way.

res = []
cur = 0
for speaker, start, end in segments:
    sent = []
    for i, (word, word_start, word_end) in enumerate(words[cur:]):
        if word_start >= end:
            cur = cur + i
            break
        sent.append(word)
    res.append((speaker, start, end, round(end - start, 2), " ".join(sent)))
    if len(sent) == len(words[cur:]):
        cur = len(words)