我正在使用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等。
任何帮助都将不胜感激。
如果要按文件名中的数字排序,则可以使用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)
您可以在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
使用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
知道如何处理的字符串。这适用于您的数据。
第二个选项打开natsort
的PATH
算法,该算法将自动正确正确处理Path
对象,并且还为文件系统路径中常见的拐角情况添加了更强大的处理。
完全公开,我是natsort
作者。