2016-12-25 42 views
0

我目前有一個問題,我必須對路徑列表進行排序。 路徑導致的文件被命名爲這樣的a-b-c.wav。如何對列表進行排序,同時對第二個列表重新排序?

這些路徑被給予其輸出兩個列表的功能,

的sampled_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 但同時確保按照data_name名稱與raw_sounds名單仍然會列出正確..

我猜我會實行人工分揀,例如名稱:

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 

我會保持這種開放的,萬一有一個內置的解決方案,我不知道的。

+1

幫助? http://stackoverflow.com/questions/13668393/python-sorting-two-lists –

+2

我們並不需要知道路徑,文件名等,這與問題無關。瞭解如何創建[mcve]。 –

+0

@ IlyaV.Schurov感謝您的鏈接..我不知道我怎麼不能測試它..數據列表是相當巨大的.. –

回答

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 

(這樣你就不需要在以後添加擴展,或擔心以後是在什麼情況下,你有數倍的)

+0

您的回答反映了我的想法,除了一些小細節:我認爲原始海報想要的文件名不帶擴展名('os.path.basename(fp)[: - 4]' )。你可以使用'os.path.splitext()'。新文件名('file_name [1] +' - '+ file_name [2] +' - '+ file_name [0]')可以用一個格式化的字符串重新構建('file_name =「{0 [1] {0 [2]} - {0 [0]}「.format(file_name)'),但像我說的那樣很小。 – EvensF

+0

@EvensF好點,我總是忘記str.format的全部力量 – Copperfield

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來處理迭代器而不是列表。