Python 中包含文本、数字和下划线的文件名排序列表
Sorting list of file name with text, number and underscore in Python
我有一个文件名列表,有些只有文字,有些有文字和数字,有些有全部。
示例:
[ 'mango_1.jpg', 'dog005.jpg', 'guru_2018_01_01.png', 'dog008.jpg', 'mango_6.jpg', 'guru_2018_5_23.png', 'dog01.png', 'mango_11.jpg', 'mango2.jpg', 'guru_2018_02_5.png', 'guru_2019_08_23.jpg', 'dog9.jpg', 'mango05.jpg' ]
我的密码是:
import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
""" Sort the given list in the way that humans expect.
"""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
l.sort( key=alphanum_key )
return print(l)
实际输出:
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_1.jpg', 'mango_6.jpg', 'mango_11.jpg']
预期输出:
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango5.jpg', 'mango_6.jpg', 'mango_11.jpg']
如何获得预期的输出?
在那种情况下,您似乎没有赋予 _
字符任何意义,请修改您的代码以排除
import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
""" Sort the given list in the way that humans expect.
"""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c.replace("_","")) for c in re.split('([0-9]+)', key) ]
l.sort( key=alphanum_key )
return print(l)
```
据我了解,您希望根据每个文件名中可能存在的 "text" 和 "date" 进行排序。所以首先你需要一个可以将文件名分成这两个部分的函数:
def split(n):
# back-to-front, find first letter index
for (i, c) in enumerate(reversed(n)):
if not (c.isdigit() or c == '_'):
break
# proper (non-reversed) index
i = len(n) - i
# split into name and date
(n, t) = (n[:i], n[i:])
# split and remove extra underscores
t = filter(bool, t.split('_'))
# convert to integers and return
return n, tuple(map(int, t))
那么你需要一个函数来删除文件名中不需要的部分(比如扩展名):
import os
def parse(n):
(n, e) = os.path.splitext(n)
return split(n)
现在您可以简单地将其用作内置 sorted
函数中的键:
>>> sorted(l, key = parse)
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_6.jpg', 'mango_11.jpg']
我有一个文件名列表,有些只有文字,有些有文字和数字,有些有全部。
示例:
[ 'mango_1.jpg', 'dog005.jpg', 'guru_2018_01_01.png', 'dog008.jpg', 'mango_6.jpg', 'guru_2018_5_23.png', 'dog01.png', 'mango_11.jpg', 'mango2.jpg', 'guru_2018_02_5.png', 'guru_2019_08_23.jpg', 'dog9.jpg', 'mango05.jpg' ]
我的密码是:
import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
""" Sort the given list in the way that humans expect.
"""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
l.sort( key=alphanum_key )
return print(l)
实际输出:
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_1.jpg', 'mango_6.jpg', 'mango_11.jpg']
预期输出:
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango5.jpg', 'mango_6.jpg', 'mango_11.jpg']
如何获得预期的输出?
在那种情况下,您似乎没有赋予 _
字符任何意义,请修改您的代码以排除
import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
""" Sort the given list in the way that humans expect.
"""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c.replace("_","")) for c in re.split('([0-9]+)', key) ]
l.sort( key=alphanum_key )
return print(l)
```
据我了解,您希望根据每个文件名中可能存在的 "text" 和 "date" 进行排序。所以首先你需要一个可以将文件名分成这两个部分的函数:
def split(n):
# back-to-front, find first letter index
for (i, c) in enumerate(reversed(n)):
if not (c.isdigit() or c == '_'):
break
# proper (non-reversed) index
i = len(n) - i
# split into name and date
(n, t) = (n[:i], n[i:])
# split and remove extra underscores
t = filter(bool, t.split('_'))
# convert to integers and return
return n, tuple(map(int, t))
那么你需要一个函数来删除文件名中不需要的部分(比如扩展名):
import os
def parse(n):
(n, e) = os.path.splitext(n)
return split(n)
现在您可以简单地将其用作内置 sorted
函数中的键:
>>> sorted(l, key = parse)
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_6.jpg', 'mango_11.jpg']