2012-08-23 716 views
20

假設我在一個文件夾中有三個文件:file9.txt,file10.txt和file11.txt,並且我想按照特定順序讀取它們。誰能幫我這個?在Python中按特定順序讀取文件

現在我使用的代碼

import glob, os 
for infile in glob.glob(os.path.join('*.txt')): 
    print "Current File Being Processed is: " + infile 

,並讀第一file10.txt然後file11.txt然後file9.txt。

有人可以幫助我如何得到正確的訂單?

回答

41

文件系統上的文件沒有排序。您可以將生成的文件名自己使用排序sorted() function

for infile in sorted(glob.glob('*.txt')): 
    print "Current File Being Processed is: " + infile 

注意,os.path.join呼叫你的代碼是一個空操作;只有一個參數,它不會做任何事情,只是返回沒有改變的參數。

請注意,您的文件將按照字母順序排序,這會將10放在9之前。您可以使用自定義按鍵功能,以提高分類:

import re 
numbers = re.compile(r'(\d+)') 
def numericalSort(value): 
    parts = numbers.split(value) 
    parts[1::2] = map(int, parts[1::2]) 
    return parts 

for infile in sorted(glob.glob('*.txt'), key=numericalSort): 
    print "Current File Being Processed is: " + infile 

numericalSort功能打出任何數字的文件名,把它變成一個實際的數量,並返回結果進行排序:

>>> files = ['file9.txt', 'file10.txt', 'file11.txt', '32foo9.txt', '32foo10.txt'] 
>>> sorted(files) 
['32foo10.txt', '32foo9.txt', 'file10.txt', 'file11.txt', 'file9.txt'] 
>>> sorted(files, key=numericalSort) 
['32foo9.txt', '32foo10.txt', 'file9.txt', 'file10.txt', 'file11.txt'] 
+0

嗨。排序的函數不幸地改變了順序。 – user1620012

+0

@ user1620012:更新了我的答案以改善排序順序。 –

+0

嗨..其實我的文件有像.. .. text-text9-text.txt,text-text10-text.txt等 – user1620012

6

您可以將glob.glob(...)表達式包含在sorted(...)語句中,並對結果列表中的文件進行排序。例如:

for infile in sorted(glob.glob('*.txt')): 

你可以給sorted一個比較函數或更好,使用key= ...參數給它一個用於排序的自定義鍵。

實施例:

有以下文件:

x/blub01.txt 
x/blub02.txt 
x/blub10.txt 
x/blub03.txt 
y/blub05.txt 

下面的代碼將產生以下輸出:與主要功能

for filename in sorted(glob.glob('[xy]/*.txt')): 
     print filename 
# x/blub01.txt 
# x/blub02.txt 
# x/blub03.txt 
# x/blub10.txt 
# y/blub05.txt 

目前:

def key_func(x): 
     return os.path.split(x)[-1] 
for filename in sorted(glob.glob('[xy]/*.txt'), key=key_func): 
     print filename 
# x/blub01.txt 
# x/blub02.txt 
# x/blub03.txt 
# y/blub05.txt 
# x/blub10.txt 

編輯: 可能此鍵功能,可以對文件進行排序:

pat=re.compile("(\d+)\D*$") 
... 
def key_func(x): 
     mat=pat.search(os.path.split(x)[-1]) # match last group of digits 
     if mat is None: 
      return x 
     return "{:>10}".format(mat.group(1)) # right align to 10 digits. 

它肯定可以改善,但我想你明白了吧。沒有數字的路徑將被單獨保留,具有數字的路徑將被轉換爲10位數字的字符串並且包含該數字。

+0

不幸的是排序的函數不會改變順序。 – user1620012

+0

它''y/blub05.txt'從最後一個位置開始移動,因爲'blub05.txt'出現在'blub10​​.txt'之前。只有文件名與'key_func'中的目錄比較。 – hochl

+0

其實我的文件沒有零。它們被重命名爲x/blub1.txt x/blub2.txt x/blub10​​.txt,即使使用sort命令,也會產生錯誤的順序。 x/blub3.txt y/blub5.txt – user1620012

-1
for fname in ['file9.txt','file10.txt','file11.txt']: 
    with open(fname) as f: # default open mode is for reading 
     for line in f: 
     # do something with line 
+0

其實我有一些我想要處理的文件。所以使列表非常不方便。 – user1620012

0
glob.glob(os.path.join('*.txt')) 

返回一個字符串列表,讓您可以輕鬆地使用排序蟒蛇sorted() function列表。

sorted(glob.glob(os.path.join('*.txt'))) 
+0

排序後的函數給出相同的結果當前正在處理的文件是:file10.txt.txt 正在處理的當前文件是:file11.txt.txt 正在處理的當前文件是:file9.txt.txt – user1620012

0

您需要通過隔離文件名中的數字來將「ASCIIBetical」從「ASCIIBetical」更改爲數字。你可以這樣做:

import re 

def keyFunc(afilename): 
    nondigits = re.compile("\D") 
    return int(nondigits.sub("", afilename)) 

filenames = ["file10.txt", "file11.txt", "file9.txt"] 

for x in sorted(filenames, key=keyFunc): 
    print xcode here 

在哪裏可以設置文件名與glob.glob(「*。txt」)的結果;

此外,keyFunc函數假定文件名將包含一個數字,並且該數字只在文件名中。您可以將該功能更改爲您需要的複雜程度,以隔離需要排序的數字。

+0

如果存在不同的文件名稱,與數字分組?防爆。 foo1.txt,foo2.txt,foo10.txt,bar1.txt,bar2.txt等等?或者文件名中有兩組數字? –

+0

@MartijnPieters:這不是原始問題的要求,我想你知道答案。 :) – grieve

+0

好吧,很可能這個問題使用了一小部分文件;事實證明'9','10','11'序列是至關重要的部分。我們不能認爲我們在這裏有全貌。 :-) –

相關問題