我有此代码:
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排序?
正则表达式不是我的强项,我无法前进。
我尝试了拆分,并且走了这么远:
nfilelist[0].split('_')[-1].split('.')
['H1', 'nc']
答案 0 :(得分:3)
假设您希望他们按 int值对其进行排序,则可以按以下方式使用regex:
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函数的调用即可。
答案 1 :(得分:0)
使用natsort模块中的sorted()
代替natsorted()
函数:
import natsort # pip install natsort
nfilelist = natsort.natsorted(glob.glob((outdir+'/*{}*.nc').format(nstring)))
(名称natsort
表示自然排序-与词典分类法相对。)
答案 2 :(得分:0)
您排序的名称具有简单且规则的结构;您无需调用正则表达式即可生存。对名称进行排序,方法是将名称的第一部分放在“ _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']
答案 3 :(得分:0)
您无需使用正则表达式即可实现
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
获取了时间