2012-08-23 28 views
20

Cho phép nói rằng tôi có ba tệp trong một thư mục: file9.txt, file10.txt và file11.txt và tôi muốn đọc chúng theo thứ tự cụ thể này. Bất cứ ai có thể giúp tôi với điều này?Đọc các tệp theo một thứ tự cụ thể trong trăn

Ngay bây giờ tôi đang sử dụng mã

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

và nó đọc file10.txt đầu tiên sau đó và sau đó file11.txt file9.txt.

Ai đó có thể giúp tôi cách nhận đúng thứ tự không?

Trả lời

41

Các tệp trên hệ thống tệp không được sắp xếp. Bạn có thể sắp xếp các tên tập tin kết quả chính mình bằng cách sử dụng sorted() function:

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

Lưu ý rằng os.path.join cuộc gọi trong mã của bạn là một không-op; với chỉ một đối số, nó không làm bất cứ điều gì, nhưng trả về đối số đó không thay đổi gì.

Lưu ý rằng các tệp của bạn sẽ sắp xếp theo thứ tự bảng chữ cái, đặt 10 trước 9. Bạn có thể sử dụng một chức năng tùy chỉnh chìa khóa để cải thiện việc phân loại:

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 

Chức năng numericalSort tách ra bất kỳ chữ số trong một tên tập tin, biến nó thành một con số thực tế, và trả kết quả để phân loại:

>>> 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

HI. Chức năng được sắp xếp không thay đổi thứ tự không may. – user1620012

+0

@ user1620012: Cập nhật câu trả lời của tôi để cải thiện thứ tự sắp xếp. –

+0

hi..các tệp của tôi có các tên như .. text-text9-text.txt, text-text10-text.txt, v.v. – user1620012

6

Bạn có thể quấn biểu thức glob.glob(...) trong câu lệnh sorted(...) và sắp xếp danh sách tệp kết quả. Ví dụ:

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

Bạn có thể cung cấp cho sorted một hàm so sánh hoặc, tốt hơn, sử dụng đối số key= ... để cho nó một phím tùy chỉnh được dùng để phân loại.

Ví dụ:

Có những file sau:

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

Đoạn mã dưới đây sẽ cho kết quả sau:

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 

Bây giờ với chức năng chính:

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 

EDIT: Có thể chức năng quan trọng này có thể sắp xếp các file của bạn:

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. 

Nó chắc chắn có thể được cải thiện, nhưng tôi nghĩ rằng bạn sẽ có được điểm. Đường dẫn không có số sẽ bị bỏ lại một mình, đường dẫn có số sẽ được chuyển thành chuỗi có 10 chữ số rộng và chứa số.

+0

Chức năng được sắp xếp không thay đổi thứ tự không may. – user1620012

+0

Nó hoạt động - 'y/blub05.txt' di chuyển từ vị trí cuối cùng lên vì' blub05.txt' xuất hiện trước 'blub10.txt'. Chỉ tên tệp được so sánh mà không có thư mục trong 'key_func'. – hochl

+0

Thực ra các tệp của tôi không có số không. Chúng được đổi tên thành x/blub1.txt x/blub2.txt x/blub10.txt và điều này tạo ra thứ tự sai, ngay cả với lệnh sắp xếp. 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

Thực ra tôi có một vài tệp hundrdes mà tôi muốn xử lý. Làm cho danh sách này khá bất tiện. – user1620012

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

trả về danh sách các chuỗi để bạn có thể dễ dàng sắp xếp danh sách bằng cách sử dụng pythons sorted() function.

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

chức năng được sắp xếp cho cùng một kết quả Tệp hiện tại đang được xử lý là: file10.txt.txt Tệp hiện tại đang được xử lý là: file11.txt.txt Tệp hiện tại đang được xử lý là: file9.txt.txt – user1620012

0

Bạn cần thay đổi loại từ 'ASCIIBetical' thành số bằng cách tách số trong tên tệp. Bạn có thể làm như vậy:

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 

Nơi bạn có thể đặt tên tệp bằng kết quả glob.glob ("*. Txt");

Bổ sung chức năng keyFunc giả định tên tệp sẽ có số trong đó và số đó chỉ có trong tên tệp. Bạn có thể thay đổi hàm đó thành phức tạp vì bạn cần cách ly số bạn cần sắp xếp.

+0

Điều gì sẽ xảy ra nếu có tệp khác nhau tên, được nhóm với số? Ví dụ 'foo1.txt',' foo2.txt' .. 'foo10.txt', sau đó' bar1.txt', 'bar2.txt', v.v ...? Hoặc có hai bộ số trong tên tệp? –

+0

@MartijnPieters: Đó không phải là yêu cầu của câu hỏi ban đầu, và tôi nghĩ bạn biết câu trả lời. :) – grieve

+0

Vâng, rất có thể câu hỏi đã sử dụng một mẫu nhỏ các tệp; khi nó chỉ ra chuỗi '9',' 10', '11' là phần quan trọng. Chúng ta không thể cho rằng chúng ta có toàn bộ bức tranh ở đây. :-) –

Các vấn đề liên quan