如何自然地对“ WindowsPath”对象文件进行排序

问题描述 投票:1回答:3

我正在使用Path()。glob()遍历目录中的文件,并且没有以正确的自然顺序进行迭代。例如。它像这样迭代:

[WindowsPath('C:/Users/HP/Desktop/P1/dataP1/SAMPLED_NORMALIZED/P1_Cor.csv'),
 WindowsPath('C:/Users/HP/Desktop/P10/dataP10/SAMPLED_NORMALIZED/P10_Cor.csv'),
 WindowsPath('C:/Users/HP/Desktop/P11/dataP11/SAMPLED_NORMALIZED/P11_Cor.csv'),
 WindowsPath('C:/Users/HP/Desktop/P12/dataP12/SAMPLED_NORMALIZED/P12_Cor.csv'),
# ...and so on from P1 to P30

[当我希望它如此迭代时:P1,P2,P3等。

我尝试使用下面的代码,但它给我一个错误:

from pathlib import Path

file_path = r'C:/Users/HP/Desktop'

files = Path(file_path).glob(file)
sorted(files, key=lambda name: int(name[10:]))

其中10只是我尝试代码时的一些小数字。

错误:

TypeError: 'WindowsPath' object is not subscriptable

最终,我要遍历文件并对每个文件执行一些操作:

from pathlib import Path

for i, fl in enumerate(Path(file_path).glob(file)):
    # do something

我什至尝试了库natsort,但在迭代中未正确排序文件。我已经尝试过:

from natsort import natsort_keygen, ns
natsort_key1 = natsort_keygen(key=lambda y: y.lower())
from natsort import natsort_keygen, ns
natsort_key2 = natsort_keygen(alg=ns.IGNORECASE)

上面的两个代码仍然给我P1,P10,P11等。

任何帮助都将不胜感激。

python glob pathlib natsort
3个回答
2
投票

如果要按文件名中的数字排序,则可以使用Path.name属性和提取数字的正则表达式。

from pathlib import Path
import re

file_path = r'C:/Users/HP/Desktop/P1/dataP1/SAMPLED_NORMALIZED/'

def _p_file_sort_key(file_path):
    """Given a file in the form P(digits)_cor.csv, return digits as an int"""
    return int(re.match(r"P(\d+)", file_path.name).group(1))

files = sorted(Path(file_path).glob("P*_Cor.csv"), key=_p_file_sort_key)

0
投票

您可以在Path对象上调用str,也可以使用as_posix()

from pathlib import Path

for fn in sorted([str(p) for p in Path(file_path).glob('*.csv')]):
    # do something with fn

for fn in sorted([p.as_posix() for p in Path(file_path).glob('*.csv')]):
    # do something with fn


0
投票

使用natsort可以对这些数据进行排序,但是您必须告诉它如何提取Path对象的字符串(出于性能目的,默认情况下它不会这么做)。

In [2]: from pathlib import Path                                                                                    

In [3]: import natsort                                                                                              

In [4]: a = [Path('C:/Users/HP/Desktop/P1/dataP1/SAMPLED_NORMALIZED/P1_Cor.csv'),
             Path('C:/Users/HP/Desktop/P10/dataP10/SAMPLED_NORMALIZED/P10_Cor.csv'),
             Path('C:/Users/HP/Desktop/P2/dataP2/SAMPLED_NORMALIZED/P2_Cor.csv')]                                                                       

In [5]: natsort.natsorted(a, key=str)                                                                                      
Out[5]: 
[PosixPath('C:/Users/HP/Desktop/P1/dataP1/SAMPLED_NORMALIZED/P1_Cor.csv'),
 PosixPath('C:/Users/HP/Desktop/P2/dataP2/SAMPLED_NORMALIZED/P2_Cor.csv'),
 PosixPath('C:/Users/HP/Desktop/P10/dataP10/SAMPLED_NORMALIZED/P10_Cor.csv')]

In [6]: natsort.natsorted(a, alg=natsort.PATH)
Out[6]: 
[PosixPath('C:/Users/HP/Desktop/P1/dataP1/SAMPLED_NORMALIZED/P1_Cor.csv'),
 PosixPath('C:/Users/HP/Desktop/P2/dataP2/SAMPLED_NORMALIZED/P2_Cor.csv'),
 PosixPath('C:/Users/HP/Desktop/P10/dataP10/SAMPLED_NORMALIZED/P10_Cor.csv')]

第一个选项将把所有Path对象转换为natsort知道如何处理的字符串。这适用于您的数据。

第二个选项打开natsortPATH算法,该算法将自动正确正确处理Path对象,并且还为文件系统路径中常见的拐角情况添加了更强大的处理。


完全公开,我是natsort作者。

© www.soinside.com 2019 - 2024. All rights reserved.