【问题标题】:Sort filenames in directory in ascending order [duplicate]按升序对目录中的文件名进行排序[重复]
【发布时间】:2016-01-14 12:50:48
【问题描述】:

我有一个目录,里面有 jpg 和其他文件,这些 jpg 都有文件名,里面有数字。有些可能在文件名中有额外的字符串。

例如。

01.jpg

也可以

Picture 03.jpg

在 Python 中,我需要按升序排列的所有 jpg 列表。 这是这个的代码sn-p

import os
import numpy as np

myimages = [] #list of image filenames
dirFiles = os.listdir('.') #list of directory files
dirFiles.sort() #good initial sort but doesnt sort numerically very well
sorted(dirFiles) #sort numerically in ascending order

for files in dirFiles: #filter out all non jpgs
    if '.jpg' in files:
        myimages.append(files)
print len(myimages)
print myimages

我得到的是这个

['0.jpg', '1.jpg', '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg',
 '15.jpg', '16.jpg', '17.jpg', '18.jpg', '19.jpg', '2.jpg', '20.jpg',
 '21.jpg', '22.jpg', '23.jpg', '24.jpg', '25.jpg', '26.jpg', '27.jpg',
 '28.jpg', '29.jpg', '3.jpg', '30.jpg', '31.jpg', '32.jpg', '33.jpg',
 '34.jpg', '35.jpg', '36.jpg', '37.jpg', '4.jpg', '5.jpg', '6.jpg',
 '7.jpg', '8.jpg', '9.jpg']

显然,它首先对最重要的数字进行盲目排序。我尝试使用sorted(),如您所见,希望它能修复它,但没有任何区别。

【问题讨论】:

  • fnames = sorted([fname for fname in os.listdir('.') if fname.endswith('.jpg')], key=lambda f: int(f.rsplit(os.path.extsep, 1)[0].rsplit(None,1)[-1]))
  • 这是因为list元素是strings
  • @inspectorG4dget,你也可以使用生成器理解。
  • @cris:没有。 sorted 无论如何都会列出它

标签: python sorting


【解决方案1】:

假设每个文件名中只有一个数字:

>>> dirFiles = ['Picture 03.jpg', '02.jpg', '1.jpg']
>>> dirFiles.sort(key=lambda f: int(filter(str.isdigit, f)))
>>> dirFiles
['1.jpg', '02.jpg', 'Picture 03.jpg']

同样适用于 Python 3 的版本:

>>> dirFiles.sort(key=lambda f: int(re.sub('\D', '', f)))

【讨论】:

  • 也可以!非常干净我最喜欢你的解决方案。但是如果列表中有一个由于某种原因没有数字的元素,它将失败。但我只是确保在 myimages[] 中进行排序,名称中肯定会有一个数字。
  • @user3474042 是的,如果所有的 jpeg 都有数字,那么就可以了。否则,可能使用int(filter(str.isdigit, f) or -1))(这会将无数字文件名放在前面)。顺便说一句,看看glob 模块,它可以让你直接请求*.jpg 文件。
  • 用于 python 3 的 Lambda 变得更丑:lambda f: int(''.join(filter(str.isdigit, f))))(否则它会抱怨 int() 参数必须是字符串、类似字节的对象或数字,而不是 'filter '…我想念 ruby​​ 的鸭式打字…)
  • 是的,正如@melboiko 所说,您的答案仅适用于 Python 2
  • @Timo 当然你会得到None。和其他人一样。所以正确地应用它,就像我展示的那样。或者使用sorted,它会返回一个排序列表而不是就地排序。
【解决方案2】:

有一个模块natsort。只需pip install natsort

>>> import natsort 
>>> ll = ['Picture 13.jpg', 'Picture 14.jpg', 'Picture 15.jpg','Picture 0.jpg', 'Picture 1.jpg', 'Picture 10.jpg', 'Picture 11.jpg', 'Picture 12.jpg',  'Picture 16.jpg', 'Picture 17.jpg', 'Picture 18.jpg', 'Picture 19.jpg', 'Picture 2.jpg', 'Picture 20.jpg', 'Picture 21.jpg', 'Picture 22.jpg', 'Picture 23.jpg', 'Picture 24.jpg', 'Picture 25.jpg', 'Picture 26.jpg', 'Picture 27.jpg', 'Picture 28.jpg', 'Picture 29.jpg', 'Picture 3.jpg', 'Picture 30.jpg', 'Picture 31.jpg', 'Picture 32.jpg', 'Picture 33.jpg', 'Picture 34.jpg', 'Picture 35.jpg', 'Picture 36.jpg', 'Picture 37.jpg']         
>>> print(natsort.natsorted(ll,reverse=True))
['Picture 37.jpg', 'Picture 36.jpg', 'Picture 35.jpg', 'Picture 34.jpg', 'Picture 33.jpg', 'Picture 32.jpg', 'Picture 31.jpg', 'Picture 30.jpg', 'Picture 29.jpg', 'Picture 28.jpg', 'Picture 27.jpg', 'Picture 26.jpg', 'Picture 25.jpg', 'Picture 24.jpg', 'Picture 23.jpg', 'Picture 22.jpg', 'Picture 21.jpg', 'Picture 20.jpg', 'Picture 19.jpg', 'Picture 18.jpg', 'Picture 17.jpg', 'Picture 16.jpg', 'Picture 15.jpg', 'Picture 14.jpg', 'Picture 13.jpg', 'Picture 12.jpg', 'Picture 11.jpg', 'Picture 10.jpg', 'Picture 3.jpg', 'Picture 2.jpg', 'Picture 1.jpg', 'Picture 0.jpg']

【讨论】:

  • 我收到 ValueError: invalid literal for int() with base 10:
  • 我找到了更好的解决方案。现在会更新。但我没有收到数据错误。如果您只有数字作为名称应该适合您。但既然有通用方法,您可能会更喜欢它。
  • 仅供参考,看起来安装命令是pip install natsort。多年来可能发生了变化,我不完全确定。
【解决方案3】:

我有一个目录,里面有 jpg 和其他文件。

[...]

['0.jpg', '1.jpg', '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg', '15.jpg', '16.jpg', '17.jpg', '18.jpg', '19.jpg', '2.jpg', '20.jpg', '21.jpg', '22.jpg', '23.jpg', '24.jpg', '25.jpg', '26.jpg', '27.jpg', '28.jpg', '29.jpg', '3.jpg', '30.jpg', '31.jpg', '32.jpg', '33.jpg', '34.jpg', '35.jpg', '36.jpg', '37.jpg', '4.jpg', '5.jpg', '6.jpg', '7.jpg', '8.jpg', '9.jpg'] 显然它最盲目地排序 重要的数字。如您所见,我尝试使用 sorted() 它会修复它,但它没有任何区别

您可以使用 splitext 获取没有扩展名的部分并将其转换为 int 进行排序。如果列表名为“l”且排序列表名为“lsorted”,您可以使用:

lsorted = sorted(imgs_list, key=lambda x: int(os.path.splitext(x)[0]))

"imgs_list" 这里是图片列表。如果您有图像目录,只需通过以下方式获取这些图像的列表:

l = os.listdir('/path/to/directory/of/images')

解释:'10.jpg' 上的 os.path.splitext 返回 ['10','.jpg'] 因此,只要文件名没有扩展名,采用元素零的 int() 即可满足您的需求仅包含可以使用 int() 转换为整数的字符串。否则你会遇到错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2018-11-10
    相关资源
    最近更新 更多