Python 如何按数字而不是字符串对列表排序?
我有以下代码:Python 如何按数字而不是字符串对列表排序?,python,regex,list,sorting,Python,Regex,List,Sorting,我有以下代码: import glob, os outdir = './output/' nstring = 'testdat_2014-12-31' nfilelist = sorted(glob.glob((outdir+'/*{}*.nc').format(nstring))) 我从中获得nfilelist: ['testdat_2014-12-31-21_H1.nc', 'testdat_2014-12-31-21_H10.nc', 'testdat_2014-12-31-21_H
import glob, os
outdir = './output/'
nstring = 'testdat_2014-12-31'
nfilelist = sorted(glob.glob((outdir+'/*{}*.nc').format(nstring)))
我从中获得nfilelist
:
['testdat_2014-12-31-21_H1.nc',
'testdat_2014-12-31-21_H10.nc',
'testdat_2014-12-31-21_H11.nc',
'testdat_2014-12-31-21_H12.nc',
'testdat_2014-12-31-21_H2.nc',
'testdat_2014-12-31-21_H3.nc',
'testdat_2014-12-31-21_H4.nc',
'testdat_2014-12-31-21_H5.nc',
'testdat_2014-12-31-21_H6.nc',
'testdat_2014-12-31-21_H7.nc',
'testdat_2014-12-31-21_H8.nc',
'testdat_2014-12-31-21_H9.nc']
最后的H1-H12数字反映了我想要如何对其进行排序。但现在,H10-H12被夹在中间。如何从H1-H12排序
Regex不是我的强项,我无法前进
我试着分开,走了这么远:
nfilelist[0].split('_')[-1].split('.')
['H1', 'nc']
假设您希望它们按int值排序,则可以按以下方式使用:
import re
nfiles = ['testdat_2014-12-31-21_H1.nc',
'testdat_2014-12-31-21_H10.nc',
'testdat_2014-12-31-21_H11.nc',
'testdat_2014-12-31-21_H12.nc',
'testdat_2014-12-31-21_H2.nc',
'testdat_2014-12-31-21_H3.nc',
'testdat_2014-12-31-21_H4.nc',
'testdat_2014-12-31-21_H5.nc',
'testdat_2014-12-31-21_H6.nc',
'testdat_2014-12-31-21_H7.nc',
'testdat_2014-12-31-21_H8.nc',
'testdat_2014-12-31-21_H9.nc']
result = sorted(nfiles, key=lambda x: int(re.search('H(\d+)\.nc', x).group(1)))
print(result)
输出
['testdat_2014-12-31-21_H1.nc', 'testdat_2014-12-31-21_H2.nc', 'testdat_2014-12-31-21_H3.nc', 'testdat_2014-12-31-21_H4.nc', 'testdat_2014-12-31-21_H5.nc', 'testdat_2014-12-31-21_H6.nc', 'testdat_2014-12-31-21_H7.nc', 'testdat_2014-12-31-21_H8.nc', 'testdat_2014-12-31-21_H9.nc', 'testdat_2014-12-31-21_H10.nc', 'testdat_2014-12-31-21_H11.nc', 'testdat_2014-12-31-21_H12.nc']
解释
模式'H(\d+)\.nc'
表示匹配任何一组数字(\d+)
,前面是H
,后面是.nc
。并使用.group(1)
获取数字组。然后将这些数字组转换为int
,并将它们用作排序的键
无正则表达式
如果要完全避免使用正则表达式,请使用以下函数作为键:
def key(element):
digits = (ix for ix in element.split('_')[-1] if ix.isdigit())
return int(''.join(digits))
result = sorted(nfiles, key=key)
print(result)
注意
最后,如果要按字符串值排序,只需删除对int函数的调用。假设要按int值排序,可以按以下方式使用:
import re
nfiles = ['testdat_2014-12-31-21_H1.nc',
'testdat_2014-12-31-21_H10.nc',
'testdat_2014-12-31-21_H11.nc',
'testdat_2014-12-31-21_H12.nc',
'testdat_2014-12-31-21_H2.nc',
'testdat_2014-12-31-21_H3.nc',
'testdat_2014-12-31-21_H4.nc',
'testdat_2014-12-31-21_H5.nc',
'testdat_2014-12-31-21_H6.nc',
'testdat_2014-12-31-21_H7.nc',
'testdat_2014-12-31-21_H8.nc',
'testdat_2014-12-31-21_H9.nc']
result = sorted(nfiles, key=lambda x: int(re.search('H(\d+)\.nc', x).group(1)))
print(result)
输出
['testdat_2014-12-31-21_H1.nc', 'testdat_2014-12-31-21_H2.nc', 'testdat_2014-12-31-21_H3.nc', 'testdat_2014-12-31-21_H4.nc', 'testdat_2014-12-31-21_H5.nc', 'testdat_2014-12-31-21_H6.nc', 'testdat_2014-12-31-21_H7.nc', 'testdat_2014-12-31-21_H8.nc', 'testdat_2014-12-31-21_H9.nc', 'testdat_2014-12-31-21_H10.nc', 'testdat_2014-12-31-21_H11.nc', 'testdat_2014-12-31-21_H12.nc']
解释
模式'H(\d+)\.nc'
表示匹配任何一组数字(\d+)
,前面是H
,后面是.nc
。并使用.group(1)
获取数字组。然后将这些数字组转换为int
,并将它们用作排序的键
无正则表达式
如果要完全避免使用正则表达式,请使用以下函数作为键:
def key(element):
digits = (ix for ix in element.split('_')[-1] if ix.isdigit())
return int(''.join(digits))
result = sorted(nfiles, key=key)
print(result)
注意
最后,如果要按字符串值排序,只需删除对int函数的调用。而不是sorted()
函数,请使用模块中的natsorted()
函数:
(名称natsort
表示自然排序,与词典排序相反。)使用模块中的natsorted()
函数代替sorted()
函数:
(名称
natsort
表示自然排序,而不是字典排序)。您排序的名称具有简单而规则的结构;您可以不调用正则表达式而生存下来。通过将名称的第一部分置于“_H”之后,然后将其第一部分置于“.”之前,并将结果转换为整数,对名称进行排序:
sorted(nfilelist,
key=lambda x: int(x.split("_H")[1].split(".")[0]))
#['testdat_2014-12-31-21_H1.nc', 'testdat_2014-12-31-21_H2.nc',
# 'testdat_2014-12-31-21_H3.nc', 'testdat_2014-12-31-21_H4.nc',
# 'testdat_2014-12-31-21_H5.nc', 'testdat_2014-12-31-21_H6.nc',
# 'testdat_2014-12-31-21_H7.nc', 'testdat_2014-12-31-21_H8.nc',
# 'testdat_2014-12-31-21_H9.nc', 'testdat_2014-12-31-21_H10.nc',
# 'testdat_2014-12-31-21_H11.nc', 'testdat_2014-12-31-21_H12.nc']
您排序的名称具有简单且规则的结构;您可以不调用正则表达式而生存下来。通过将名称的第一部分置于“_H”之后,然后将其第一部分置于“.”之前,并将结果转换为整数,对名称进行排序:
sorted(nfilelist,
key=lambda x: int(x.split("_H")[1].split(".")[0]))
#['testdat_2014-12-31-21_H1.nc', 'testdat_2014-12-31-21_H2.nc',
# 'testdat_2014-12-31-21_H3.nc', 'testdat_2014-12-31-21_H4.nc',
# 'testdat_2014-12-31-21_H5.nc', 'testdat_2014-12-31-21_H6.nc',
# 'testdat_2014-12-31-21_H7.nc', 'testdat_2014-12-31-21_H8.nc',
# 'testdat_2014-12-31-21_H9.nc', 'testdat_2014-12-31-21_H10.nc',
# 'testdat_2014-12-31-21_H11.nc', 'testdat_2014-12-31-21_H12.nc']
无需使用正则表达式就可以实现这一点
result = sorted(nfilelist, key=lambda x: (len(x), x))
该键首先将这些文件名与
| Method | Timing |
+-------------------+------------------------------+
| Using natsort | 219 µs ± 1.13 µs per loop |
| Daniel's regex | 14.2 µs ± 434 ns per loop |
| Daniel's no-regex | 14.2 µs ± 101 ns per loop |
| DYZ's split based | 7.50 µs ± 240 ns per loop |
| This answer | 2.77 µs ± 46.6 ns per loop |
计时是使用在2.7 GHz Intel Core i7上运行的iPython3.7中的
%timeit
获得的。您无需使用正则表达式即可实现此目的
result = sorted(nfilelist, key=lambda x: (len(x), x))
该键首先将这些文件名与
| Method | Timing |
+-------------------+------------------------------+
| Using natsort | 219 µs ± 1.13 µs per loop |
| Daniel's regex | 14.2 µs ± 434 ns per loop |
| Daniel's no-regex | 14.2 µs ± 101 ns per loop |
| DYZ's split based | 7.50 µs ± 240 ns per loop |
| This answer | 2.77 µs ± 46.6 ns per loop |
使用运行在2.7 GHz Intel Core i7上的iPython3.7中的
%timeit
获得计时。请参阅@maximusdooku是否要按int值或字符串值排序?请参阅@maximusdooku是否要按int值或字符串值排序?如果您有一个名为testdat_2018-12-31-21_H0.nc;的文件,此解决方案将失败。)@LakshayGarg根据OP,这是不可能的:nstring='testdat_2014-12-31'
。如果您有一个名为testdat_2018-12-31-21_H0.nc;的文件,此解决方案将失败。)@LakshayGarg根据OP,这是不可能的:nstring='testdat_2014-12-31'
。