[英]How to sort a list a string of two list path in python?
我有兩個包含文件路徑的列表
lst_A =['/home/data_A/test_AA_123.jpg',
'/home/data_A/test_AB_234.jpg',
'/home/data_A/test_BB_321.jpg',
'/home/data_A/test_BC_112.jpg',
]
lst_B =['/home/data_B/test_AA_222.jpg',
'/home/data_B/test_CC_444.jpg',
'/home/data_B/test_AB_555.jpg',
'/home/data_B/test_BC_777.jpg',
]
基於lst_A
,我想對列表B進行排序,以使A和B中兩個路徑的基名的名字和名字應該相同。 在這種情況下是test_xx
。 因此,預期的候選清單B為
lst_B =['/home/data_B/test_AA_222.jpg',
'/home/data_B/test_AB_555.jpg',
'/home/data_B/test_CC_444.jpg',
'/home/data_B/test_BC_777.jpg',
]
另外,我想指出兩個列表中哪個位置的名字中的名字和名字相同(例如test_xx
),因此數組指示符應為
array_same =[1,1,0,1]
我應該如何在python中做到這一點? 我已經嘗試過.sort()函數,但是它返回了意外的結果。 謝謝
更新:這是我的解決方案
import os
lst_A =['/home/data_A/test_AA_123.jpg',
'/home/data_A/test_AB_234.jpg',
'/home/data_A/test_BB_321.jpg',
'/home/data_A/test_BC_112.jpg',
]
lst_B =['/home/data_B/test_AA_222.jpg',
'/home/data_B/test_CC_444.jpg',
'/home/data_B/test_AB_555.jpg',
'/home/data_B/test_BC_777.jpg']
lst_B_sort=[]
same_array=[]
for ind_a, a_name in enumerate(lst_A):
for ind_b, b_name in enumerate(lst_B):
print (os.path.basename(b_name).split('_')[1])
if os.path.basename(b_name).split('_')[1] in os.path.basename(a_name):
lst_B_sort.append(b_name)
same_array.append(1)
print(lst_B_sort)
print(same_array)
Output: ['/home/data_B/test_AA_222.jpg', '/home/data_B/test_AB_555.jpg', '/home/data_B/test_BC_777.jpg']
[1, 1, 1]
因為我沒有添加名稱不同的元素
遍歷lst_A
,獲取文件名前綴,然后將lst_B
具有相同前綴的元素追加到結果列表中。
從lst_B
創建所有元素的lst_B
,然后在結果中添加路徑時,將其從集合中刪除。 然后,最后您可以遍歷此集合,在沒有匹配項的結果中填充空白。
lst_A =['/home/data_A/test_AA_123.jpg',
'/home/data_A/test_AB_234.jpg',
'/home/data_A/test_BB_321.jpg',
'/home/data_A/test_BC_112.jpg',
]
lst_B =['/home/data_B/test_AA_222.jpg',
'/home/data_B/test_CC_444.jpg',
'/home/data_B/test_AB_555.jpg',
'/home/data_B/test_BC_777.jpg',
]
new_lst_B = []
same_array = []
set_B = set(lst_B)
for fn in lst_A:
prefix = "_".join(os.path.basename(fn).split('_')[:-1])+'_' # This gets test_AA_
try:
found_B = next(x for x in lst_B if os.path.basename(x).startswith(prefix))
new_lst_b.append(found_B)
same_array.append(1)
set_B.remove(found_B)
except StopIteration: # No match found
new_lst_b.append(None) # Placeholder to fill in
same_array.append(0)
for missed in set_B:
index = new_lst_B.index(None)
new_lst_B[index] = missed
我們將使用SIMPLE技術和應用解決方案討論該問題。
簡單
我們只專注於對給定鍵的名稱進行排序。
特定
簡單名稱和鍵列表:
lst_a = "AA AB BB BC EE".split()
lst_b = "AA DD CC AB BC".split()
key_list = [1, 1, 0, 1, 0]
碼
same = sorted(set(lst_a) & set(lst_b))
diff = sorted(set(lst_b) - set(same))
isame, idiff = iter(same), iter(diff)
[next(isame) if x else next(idiff) for x in key_list]
# ['AA', 'AB', 'CC', 'BC', 'DD']
lst_b
根據與lst_a
共享的元素進行排序。 根據需要插入殘余物。
細節
這個問題主要減少到對兩個列表中的名稱交集進行排序。 相交是一組稱為same
的公共元素。 殘留物位於diff
。 我們的排序same
和diff
,在這里就是他們的樣子:
same
# ['AA', 'AB', 'BC']
diff
# ['CC', 'DD']
現在,我們只想根據鍵從任一列表中按順序提取值。 我們從迭代key_list
開始。 如果為1
,則從isame
迭代器中提取。 否則,請從idiff
。
現在我們有了基本技術,我們可以將其應用於更復雜的路徑示例。
應用
將此想法應用於更復雜的路徑字符串:
特定
import pathlib
lst_a = "foo/t_AA_a.jpg foo/t_AB_a.jpg foo/t_BB_a.jpg foo/t_BC_a.jpg foo/t_EE_a.jpg".split()
lst_b = "foo/t_AA_b.jpg foo/t_DD_b.jpg foo/t_CC_b.jpg foo/t_AB_b.jpg foo/t_BC_b.jpg".split()
key_list = [1, 1, 0, 1, 0]
# Helper
def get_name(s_path):
"""Return the shared 'name' from a string path.
Examples
--------
>>> get_name("foo/test_xx_a.jpg")
'test_xx'
"""
return pathlib.Path(s_path).stem.rsplit("_", maxsplit=1)[0]
碼
將名稱映射到路徑:
name_path_a = {get_name(p): p for p in lst_a}
name_path_b = {get_name(p): p for p in lst_b}
名稱在字典鍵中,因此直接用字典鍵替換集:
same = sorted(name_path_a.keys() & name_path_b.keys())
diff = sorted(name_path_b.keys() - set(same))
isame, idiff = iter(same), iter(diff)
通過從迭代器提取的名稱獲取路徑:
[name_path_b[next(isame)] if x else name_path_b[next(idiff)] for x in key_list]
產量
['foo/t_AA_b.jpg',
'foo/t_AB_b.jpg',
'foo/t_CC_b.jpg',
'foo/t_BC_b.jpg',
'foo/t_DD_b.jpg']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.