如何自然地对 'WindowsPath' 个目标文件进行排序
How to sort 'WindowsPath' object files naturally
我正在使用 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 对象上调用 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
如果要按文件名中的数字排序,可以使用 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)
使用 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
作者。
我正在使用 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 对象上调用 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
如果要按文件名中的数字排序,可以使用 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)
使用 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
作者。