对os.listdir文件进行Python排序

对os.listdir文件进行Python排序,python,file,sorting,python-2.7,io,Python,File,Sorting,Python 2.7,Io,如果您下载了存储在具有以下命名约定的文件中的数年数据,则为year_day.dat。例如,名为2014_1.dat的文件包含2014年1月1日的数据。我需要阅读这些数据文件,从2014年1月1日、2014年2月2日、2014年3月3日到年底。在文件夹中,它们按顺序列出,但当我在目录中创建文件列表时,它们被重新排序为2014_1.dat、2014_10.dat、2014_100.dat、2014_101.dat…2014.199.dat、2014_2.dat。 我想我需要使用排序功能,但如何强制它

如果您下载了存储在具有以下命名约定的文件中的数年数据,则为year_day.dat。例如,名为2014_1.dat的文件包含2014年1月1日的数据。我需要阅读这些数据文件,从2014年1月1日、2014年2月2日、2014年3月3日到年底。在文件夹中,它们按顺序列出,但当我在目录中创建文件列表时,它们被重新排序为2014_1.dat、2014_10.dat、2014_100.dat、2014_101.dat…2014.199.dat、2014_2.dat。 我想我需要使用排序功能,但如何强制它按天对列出的文件进行排序,以便我可以继续处理它们? 以下是迄今为止的代码:

import sys, os, gzip, fileinput, collections
# Set the input/output directories
wrkDir = "C:/LJBTemp"
inDir = wrkDir + "/Input"
outDir = wrkDir + "/Output"
# here we go
inList = os.listdir(inDir)  # List all the files in the 'Input' directory
print inList  #print to screen reveals 2014_1.dat.gz followed by 2014_10.dat.gz NOT    2014_2.dat.gz HELP
d = {}
for fileName in inList:     # Step through each input file 
    readFileName = inDir + "/" + fileName

    with gzip.open(readFileName, 'r') as f: #call built in utility to unzip file for reading
      for line in f:
          city, long, lat, elev, temp = line.split() #create dictionary
          d.setdefault(city, []).append(temp) #populate dictionary with city and associated temp data from each input file
          collections.OrderedDict(sorted(d.items(), key=lambda d: d[0])) # QUESTION? why doesn't this work
          #now collect and write to output file
outFileName = outDir + "/" + "1981_maxT.dat" #create output file in output directory with .dat extension
with open(outFileName, 'w') as f:
     for city, values in d.items():
        f.write('{} {}\n'.format(city, ' '.join(values)))

print "All done!!"
raw_input("Press <enter>") # this keeps the window open until you press "enter"
导入系统、操作系统、gzip、文件输入、集合
#设置输入/输出目录
wrkDir=“C:/LJBTemp”
inDir=wrkDir+“/Input”
outDir=wrkDir+“/Output”
#我们开始
inList=os.listdir(inDir)#列出“Input”目录中的所有文件
打印列表#打印到屏幕显示2014_1.dat.gz,然后是2014_10.dat.gz,而不是2014_2.dat.gz帮助
d={}
对于inList中的文件名:#逐步浏览每个输入文件
readFileName=inDir+“/”+文件名
使用gzip.open(readFileName,'r')作为f:#调用内置实用程序解压缩文件以进行读取
对于f中的行:
city、long、lat、elev、temp=line.split()#创建字典
d、 setdefault(city,[])。append(temp)#使用每个输入文件中的city和相关temp数据填充字典
collections.OrderedDict(已排序(d.items(),key=lambda d:d[0])#问题?为什么这个不行
#现在收集并写入输出文件
outFileName=outDir+“/”+“1981_maxT.dat”#在输出目录中创建扩展名为.dat的输出文件
以开放式(outFileName,'w')作为f:
对于城市,d.items()中的值:
f、 写入('{}{}\n'.格式(城市,'.join(值)))
打印“全部完成!!”
原始输入(“按”)#这将保持窗口打开,直到您按“回车”键

如果您的所有文件都以“2014”开头,请尝试以下操作:

sorted(inList, key = lambda k: int(k.split('_')[1].split('.')[0]))
否则,利用元组比较,先按年份排序,然后按文件名的第二部分排序

sorted(inList, key = lambda k: (int(k.split('_')[0]), int(k.split('_')[1].split('.')[0])))

dict.items
返回
(键,项)
对的列表

key函数仅使用第一个元素(
d[0]
=>
key
=>city)

还有另一个问题:
sorted
返回已排序列表的新副本,但不在原地对列表进行排序。另外,创建了
OrderedDict
对象,并且没有在任何地方分配该对象;实际上,您不需要在每次将项目附加到列表时进行排序

正在删除
。。。已排序…
行,并替换以下行:

with open(outFileName, 'w') as f:
     for city, values in d.items():
        f.write('{} {}\n'.format(city, ' '.join(values)))
使用以下方法可以解决您的问题:

with open(outFileName, 'w') as f:
     for city, values in d.items():
        values.sort(key=lambda fn: map(int, os.path.splitext(fn)[0].split('_')))
        f.write('{} {}\n'.format(city, ' '.join(values)))
顺便说一句,不要手动连接硬编码分隔符
/
,而是使用:


如果您不介意使用第三方库,您可以使用该库,它正是为这种情况而设计的

import natsort
inList = natsort.natsorted(os.listdir(inDir))
这应该考虑到所有的数字排序,而不必担心细节

您还可以使用
ns.PATH
选项使排序算法路径感知:

from natsort import natsorted, ns
inList = natsorted(os.listdir(inDir), alg=ns.PATH)


完全公开,我是natsort的作者。

谢谢你的建议。values.sort解决方案将打印输出中的值从最大值到最小值进行排序。但我要做的是复制一个输出格式,这样每次代码运行时,城市顺序都保持不变。我有30年的输入数据,需要在编码的下一阶段对输出进行标准化。@Matrix,如果您还想按城市排序,请将城市中的
,d.items()中的值替换为城市中的
,排序后的(d.items())中的值:
。谢谢您的帮助。我使用了第三方排序库natsort用于此应用程序,但将尝试您对另一个应用程序的建议。您是一个英雄!
from natsort import natsorted, ns
inList = natsorted(os.listdir(inDir), alg=ns.PATH)