如何排序列表,同时重新排序第二个列表?

时间:2016-12-25 19:03:16

标签: python list sorting

我目前遇到了问题,我必须对路径列表进行排序。 路径所指向的文件命名为a-b-c.wav。

这些路径被赋予一个输出两个列表的函数

samples_sounds列表 - (raw_sounds

file_names_of_sampled_audio的列表 - (data_name)。

功能:

def load_sound_files(file_paths):
    raw_sounds = []
    data_output = []
    data_name = []
    max = 0
    for fp in file_paths:
        y,sr = librosa.load(fp,sr=16000)
        X = librosa.util.frame(y, frame_length=400, hop_length=160)
        raw_sounds.append(X.T)
        if max < (X.shape)[1]:
            max = (X.shape)[1]
            print "New max " + str((X.shape)[1])
        index_file = list(find_all(fp,'/'))
        filename = fp[index_file[len(index_file)-1]+1:len(fp)-4]
        file_name = filename.split('-')
        file_name = file_name[1]+'-'+file_name[2]+'-'+file_name[0]
        data_name.append(file_name)
    return raw_sounds, data_name

该功能从音频采样开始。 对音频进行采样后,名称是否已重命名为 B-C-a.wav。

采样音频附加到列表raw_sounds 新名称将附加到列表data_name

这里的问题是我需要对列表data_name进行排序 但同时确保根据raw_sounds中的名称仍然正确列出data_name的列表。

我想我必须手动实现排序,例如名称:

mblw-b-an1 
mdcs2-b-an111 
mdcs2-b-an112 
mdcs2-b-an113 
mdcs2-b-an114 
mdcs2-b-an115 
fmjc-b-an116 
fmjc-b-an117 
fmjc-b-an118 
fmjc-b-an119 
fmjc-b-an120 
fjdn-b-an121 
fjdn-b-an122 

我如何对此类进行排序,同时还重新排序raw_sound,因此data_nameraw_sounds中的两个条目都包含正确的数据。

编辑:

我最终使用的解决方案是:

def resort(data_names, raw_sounds):
    data_names_bak = data_names
    data_names_sorted = sorted(data_names)
    raw_sound_output = []
    for i in range(0,len(data_names)):
        index = data_names.index(data_names_sorted[i])
        raw_sound_output.append(raw_sounds[index])
    return raw_sound_output, data_names_sorted

如果有内置解决方案,我会保持这个,我不知道。

2 个答案:

答案 0 :(得分:2)

我宁愿将两者放在同一个列表中作为元组或使用字典

如果find_all是我认为的那样,那么os.path模块就有了这个功能

>>> import os
>>> test="/path/to/my_audio/file.wav"
>>> os.path.basename(test)
'file.wav'
>>> 

然后你的函数可以重写为

import os

def load_sound_files(file_paths):
    data_output = []
    max = 0
    for fp in file_paths:
        y,sr = librosa.load(fp,sr=16000)
        X = librosa.util.frame(y, frame_length=400, hop_length=160)
        if max < (X.shape)[1]:
            max = (X.shape)[1]
            print "New max:", (X.shape)[1]
        file_name = os.path.basename(fp)[:-4].split('-')
        file_name = file_name[1]+'-'+file_name[2]+'-'+file_name[0]
        data_output.append( (file_name,X.T) )
    data_output.sort(key=lambda x: x[0])
    return data_output
    #return [ x[1] for x in data_output], [ x[0] for x in data_output  ]
    #use the commented return instead for obtain the lists with each 
    #part individually  

另请注意,您可以使用相当于some_list[-n]

的负数索引some_list[len(some_list)-n]

根据 EvensF 的建议,您可以包含文件扩展名和/或使用扩展名为.midi等不同长度的文件来提及一个,而无需修改代码。比如这样

name, ext = os.path.splitext( os.path.basename(fp) )
file_name = "{0[1]}-{0[2]}-{0[0]}".format(name.split("-")) + ext

(这样你就不需要稍后添加扩展程序,或者担心以后会有多个扩展程序)

答案 1 :(得分:0)

如果我做得对,你只需要两个排序列表:

zipped_list = zip(data_names, raw_sounds)
zipped_list.sort(key=lambda (data_names, raw_sounds): data_names)

这为您提供了一个已排序的压缩列表。

data_names, raw_sounds = zip(*zipped_list)

可以撤消压缩。

如果使用python 2.x,请考虑使用itertools.izip来处理迭代器而不是列表。