[英]How to Naturally Sort Pathlib objects in Python?
我正在尝试在./pages
目录中创建文件的排序列表。 这是我到目前为止所拥有的:
import numpy as np
from PIL import Image
import glob
from pathlib import Path
# sorted( l, key=lambda a: int(a.split("-")[1]) )
image_list = []
for filename in Path('./pages').glob('*.jpg'):
# sorted( i, key=lambda a: int(a.split("_")[1]) )
# im=Image.open(filename)
image_list.append(filename)
print(*image_list, sep = "\n")
当前 output:
pages/page_1.jpg
pages/page_10.jpg
pages/page_11.jpg
pages/page_12.jpg
pages/page_2.jpg
pages/page_3.jpg
pages/page_4.jpg
pages/page_5.jpg
pages/page_6.jpg
pages/page_7.jpg
pages/page_8.jpg
pages/page_9.jpg
预期 Output:
pages/page_1.jpg
pages/page_2.jpg
pages/page_3.jpg
pages/page_4.jpg
pages/page_5.jpg
pages/page_6.jpg
pages/page_7.jpg
pages/page_8.jpg
pages/page_9.jpg
pages/page_10.jpg
pages/page_11.jpg
pages/page_12.jpg
我尝试了在副本中找到的解决方案,但它们不起作用,因为 pathlib 文件是 class 对象,而不是字符串。 当我打印它们时,它们只显示为文件名。
例如:
print(filename) # pages/page_1.jpg
print(type(filename)) # <class 'pathlib.PosixPath'>
最后,这是工作代码。 谢谢大家。
from pathlib import Path
import numpy as np
from PIL import Image
import natsort
def merge_to_single_image():
image_list1 = []
image_list2 = []
image_list3 = []
image_list4 = []
for filename in Path('./pages').glob('*.jpg'):
image_list1.append(filename)
for i in image_list1:
image_list2.append(i.stem)
# print(type(i.stem))
image_list3 = natsort.natsorted(image_list2, reverse=False)
for i in image_list3:
i = str(i)+ ".jpg"
image_list4.append(Path('./pages', i))
images = [Image.open(i) for i in image_list4]
# for a vertical stacking it is simple: use vstack
images_combined = np.vstack(images)
images_combined = Image.fromarray(images_combined)
images_combined.save('Single_image.jpg')
只是为了后代,也许这更简洁?
natsorted(list_of_pathlib_objects, key=str)
可以使用natsort 库( pip install natsort 。它应该看起来也很简单。
[,这行得通。 至少针对版本 5.5 和 7.1(当前)进行了测试]
from natsort import natsorted
image_list = Path('./pages').glob('*.jpg')
# convert list of paths to list of string and (naturally)sort it, then convert back to list of paths
image_list = [Path(p) for p in natsorted([str(p) for p in image_list ])]
请注意, sorted
不会对您的数据进行排序,而是返回一个新列表,因此您必须对其 output 进行迭代。
为了获得您的排序键,即文件名末尾的 integer 值:
您可以首先获取路径的主干,这是它的最终组件,没有扩展名(例如, 'page_13'
)。
然后,最好从右侧拆分一次,以防您的文件名在第一部分包含其他下划线,例如'some_page_33.jpg'
。
转换为int
后,您就拥有了排序所需的密钥。
因此,您的代码可能如下所示:
for filename in sorted(Path('./pages').glob('*.jpg'),
key=lambda path: int(path.stem.rsplit("_", 1)[1])):
print(filename)
样品 output:
pages/ma_page_2.jpg
pages/ma_page_11.jpg
pages/ma_page_13.jpg
pages/ma_page_20.jpg
问题并不像听起来那么简单,“自然”排序可能非常具有挑战性,尤其是对于潜在的任意输入字符串,例如,如果您的数据中有“69_helloKitty.jpg”怎么办? 不久前我使用https://github.com/SethMorton/natsort解决了类似的问题,也许它可以帮助你。
就这样使用...
from pathlib import Path
sorted(Path('anywhere/you/want').glob('*.jpg'))
import os
sorted(Path('anywhere/you/want').glob('*.jpg'), key=os.path.getmtime)
import os
sorted(Path('anywhere/you/want').glob('*.jpg'), key=os.path.getsize)
等等
提示:因为文件名也是由您创建的。 写入文件名并添加填充零,例如:
for i in range(100):
with open('filename'+f'_{i:03d}','wb'): # py3.6+ fstring
# write your file stuff...
# py3.3+ 'filename'+'_{:03d}'.format(i) for str.format()
...
'filename_007',
'filename_008',
'filename_009',
'filename_010',
'filename_011',
'filename_012',
'filename_013',
'filename_014',
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.