2011-01-08 60 views
1

我知道sed或awk可以更優雅地處理這類問題。但是我採用了python的方式,所以問題是我想將數據文件的第一列從1重新編號到文件中的#行。通過readlines讀取文件是個好主意嗎?對於小文件也許,但大文件不是我想的。所以這就是我第一次嘗試的想法,任何意見都是值得讚賞的。更改第一列中的數字

#!/usr/bin/env python 

import sys 

try: 
    infilename = sys.argv[1]; outfilename = sys.argv[2]; 
except: 
    print "Usage is <script> inFile outFile" 

ifile = open(infilename,'r') 
ofile = open(outfilename, 'w') 

lines = ifile.readlines(); 

i=1 
for line in lines: 
    list = line.split(); 
    list[0] = i 
    i += 1 
    for val in list: 
     ofile.write("%d " % int(val)) 
    ofile.write('\n') 
    del list 

ifile.close() 
ofile.close() 
+2

不要使用分號來結束語句,這在Python中不是必需的,通常被認爲是不好的做法(因爲語句更優雅地由線返回完成)。 – 2011-01-08 23:31:49

+0

@Sylvain,習慣... – 2011-01-08 23:33:49

+0

@tokland,:對,我應該改進:) – 2011-01-08 23:38:12

回答

1

可以遍歷該文件只保留當前行存儲:

#!/usr/bin/env python 
import sys 

try: 
    # dont use ; ! 
    infilename = sys.argv[1] 
    outfilename = sys.argv[2] 
except: 
    print "Usage is <script> inFile outFile" 


# you could use `with` here if you have a Python 2.7 
ifile = open(infilename,'r') 
ofile = open(outfilename, 'w') 

# no need to count yourself, enumerate does that 
# plus when you iterate over a file you get lines too 
for i, line in enumerate(ifile, start=1): 
    # dont shadow builtins like `list` 
    parts = line.split() 
    parts[0] = i 
    # join is the inverse function to split 
    new_line = ' '.join("%d" % int(val) for val in parts) 
    ofile.write(new_line + '\n') 

ifile.close() 
ofile.close() 

@Umut Tabak機構:("%d" % int(val) for val in parts)是一個generator expression,他們有點像懶惰名單。它給出了與列表理解["%d" % int(val) for val in parts]相同的條目,但沒有實際創建列表。

順便說一句,該塊可寫入更短,但由於它不強制它是略有不同的所有線路都int小號了:

for i, line in enumerate(ifile, start=1): 
    parts = line.split() 
    parts[0] = "%d" % i 
    new_line = ' '.join(parts) 
    ofile.write(new_line + '\n') 
1

不做readlines()可言,而是:

for line in ifile: 

此外,避免名爲list變量命名。由於list()是一個內置函數,因此您將這個名稱隱藏起來是一種很差的練習。

有沒有必要del一個局部變量,就像你已經用del list;這是由Python的垃圾收集器自動處理的。 (在CPython的,垃圾收集器是引用計數和確定性。)

1
with open(infilename,'r') as ifile: 
    with open(outfilename, 'w') as ofile: 
     for (nr, line) in enumerate(ifile): 
      line = line.split() 
      line[0] = nr 
      line.append('\n') 
      ofile.write(' '.join(line)) 
1
#!/usr/bin/env python 
import sys 

try: 
    ifile = open(sys.argv[1], 'r') 
    ofile = open(sys.argv[2], 'w+') 
except: 
    print "Usage is <script> inFile outFile" 
else: 
    for i, line in enumerate(ifile, start=1): 
     items = [str(i)] + line.split()[1:] 
     ofile.write(' '.join(items) + '\n') 

    ifile.close() 
    ofile.close() 

有幾點我我喜歡和我的答案一起討論。第一個是try塊,我在那裏檢查是否可以打開這些文件。如果沒有輸入文件名,或者其中一個文件不可打開,您將收到使用信息。你當然可以分解它:檢查文本,並返回適當的返回使用,並嘗試打開文件,並適當地返回文件打開失敗。或者,您可以檢查特定的異常並返回不同的消息。

接下來,枚舉是讓解釋器記錄索引的一種便捷方式。在循環本身中,我加入了枚舉索引和讀取行的「切片」(除了第一項以外的所有內容)。然後我加入一個空格並用換行符寫入。

這是明確和短。

0

你並不需要分割的整條生產線,剛剛拆分的第一列:

for i,line in enumerate(ifile,1): 
    first,remaining = line.split(' ',1) 
    ofile.write("{0} {1}".format(i,remaining)) 

此外,您except需要退出或文件的其餘部分將要運行。