簡體   English   中英

如何在python中對列表中的兩個列表路徑的字符串進行排序?

[英]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

DEMO

我們將使用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 我們的排序samediff ,在這里就是他們的樣子:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM