简体   繁体   中英

create new list from list of lists in python by grouping

This question is related to my other question: silence out regions of audio based on a list of time stamps , using sox and python

If q= [[0.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]]

New list q' should be [4.0,10.0],[12.0,15.0],[20.0,21.0],[28.0,32.0], [36.0,41.0]]

What I did is the following:

import numpy
q= [[0.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]]
x= []       
print "in between"
for t in range(len(q)-1):
    a,b=q[t][1],q[t+1][0]
    x.append([a,b])

for i in x:
    print i

Output:

[4.0, 10.0]
[12.0, 15.0]
[20.0, 21.0]
[28.0, 32.0]
[36.0, 41.0]  

UPDATE : I want to append two more segments to my ^ ouput.

Context : These segments are time stamps.

Say the segments didn't start at zero and instead started at 3.0 q= [[3.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]] and the file ends at say 50.0.

To my original output , I want to add regions : [0.0,3] and [44.0,50.0] So that I can silence out those regions too.

For this I simply did :

import numpy
speaker_segments= [[3.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]]
segments_to_silence = []
starting= 0.0
end= 50.0
# simple output
for t in range(len(speaker_segments)-1):
        a, b = speaker_segments[t][1],speaker_segments[t+1][0]
        segments_to_silence.append([a, b])
val = len(speaker_segments)
y= speaker_segments[val-1][1]


# appending end of segment item and end of file item to output i.e [44.0,50.0]. 
if end >y:
    a,b =y,end
    segments_to_silence.append([a,b]) 

print "appending end regions"
print segments_to_silence

# appending the starting portions  0.0 - 3.0 :
f=speaker_segments[0][0]
if starting < f:
    a=starting
    b=f
    segments_to_silence.append([a,b])
print "appending beginning regions"
print segments_to_silence

OUTPUT :

appending end regions:
[[4.0, 10.0], [12.0, 15.0], [20.0, 21.0], [28.0, 32.0], [36.0, 41.0], [44.0, 50.0]]
appending beginning regions:
[[4.0, 10.0], [12.0, 15.0], [20.0, 21.0], [28.0, 32.0], [36.0, 41.0], [44.0, 50.0], [0.0, 3.0]]   

Is it possible to move the appended [0.0,3.0] to the beginning ? so that they are in a sorted list and in choronological order?

UPDATE 2: I just had to reorder the if conditionals so that the [0.0,xx] went first, then the middle and finally the end of file [50.0].

Thank you all for your quick responses! :)

With zip and list comprehension you could do the folllowing:

x = [[a[1], b[0]] for a, b in zip(q, q[1:])]

As you are using python 2 it would be better to use the iterator version of zip : itertools.izip

from itertools import izip

x = [[a[1], b[0]] for a, b in izip(q, q[1:])]

Edit: with itertools.islice as Jean-François pointed out in the comments:

from itertools import islice, izip

x = [[a[1], b[0]] for a, b in izip(q, islice(q, 1, None))]

You can flatten, discard the first and then regroup:

>>> q = [[0.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]]
>>> from itertools import chain, islice
>>> list(map(list, zip(*2*(islice(chain(*q), 1, None),))))
[[4.0, 10.0], [12.0, 15.0], [20.0, 21.0], [28.0, 32.0], [36.0, 41.0]]

Python 2 version:

>>> from itertools import chain, islice, izip
>>> map(list, izip(*2*(islice(chain(*q), 1, None),)))

You can also use itertools.groupby :

q= [[0.0,4.0], [10.0,12.0], [15.0,20.0], [21.0,28.0], [32.0,36.0],[41.0,44.0]]
new_q = list(itertools.chain.from_iterable(q))
n = [(a, list(b)) for a, b in itertools.groupby(sorted(new_q, key=lambda x:any(a == x for a, b in q)), key=lambda x:any(a == x for a, b in q))]
final_data = [[a, b] for a, b in zip(dict(n)[0], dict(n)[1][1:])]

Output:

[[4.0, 10.0], [12.0, 15.0], [20.0, 21.0], [28.0, 32.0], [36.0, 41.0]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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