像這樣的東西應該做你想要什麼。
import itertools as it
with open('test.txt') as in_file:
splitted_lines = (line.split(None, 1) for line in in_file)
for num, group in it.groupby(splitted_lines, key=lambda x: x[0]):
with open(num + '.txt', 'w') as out_file:
out_file.writelines(line for _, line in group)
- 的
with
語句可以安全地使用資源。在這種情況下,他們會自動關閉文件。
splitted_lines = (...)
行創建一個迭代遍及每個行的字段,併產生一對第一個元素,其餘行。
itertools.groupby
功能是完成大部分工作的功能。它遍歷文件的行並根據第一個元素對它們進行分組。
(line for _, line in group)
迭代「分割線」。它只是放棄第一個元素,並只寫入其餘的行。 (該_
是一個標識符,任何其他。我可以用x
或first
,但我_
經常用來表示一些你有分配,但你不使用)
我們可能可能會簡化代碼。例如最外層的with
不太可能是有用的,因爲我們只是在閱讀模式下打開文件,而不是修改它。 刪除它,我們可以脫下縮進:
import itertools as it
splitted_lines = (line.split(None, 1) for line in open('test.txt'))
for num, group in it.groupby(splitted_lines, key=lambda x: x[0]):
with open(num + '.txt', 'w') as out_file:
out_file.writelines(line for _, line in group)
我做了一個非常簡單的基準測試蟒蛇解決方案相對awk的解決方案。 性能大致相同,蟒蛇稍微更快使用一個文件,其中每行有10個字段,並與100「線組」每個隨機大小介於2和30元素之間。
時序的Python代碼的:
In [22]: from random import randint
...:
...: with open('test.txt', 'w') as f:
...: for count in range(1, 101):
...: num_nums = randint(2, 30)
...: for time in range(num_nums):
...: numbers = (str(randint(-1000, 1000)) for _ in range(10))
...: f.write('{}\t{}\n'.format(count, '\t'.join(numbers)))
...:
In [23]: %%timeit
...: splitted_lines = (line.split(None, 1) for line in open('test.txt'))
...: for num, group in it.groupby(splitted_lines, key=lambda x: x[0]):
...: with open(num + '.txt', 'w') as out_file:
...: out_file.writelines(line for _, line in group)
...:
10 loops, best of 3: 11.3 ms per loop
在awk定時:
$time awk '{print $2,$3,$4 > ("test"$1)}' OFS='\t' test.txt
real 0m0.014s
user 0m0.004s
sys 0m0.008s
注意0.014s
約爲14 ms
。
無論如何,取決於操作系統的負載,時間可能會有所不同,並且它們同樣有效。在實踐中,幾乎所有的時間都是從文件中讀取/寫入文件,這是由python和awk高效地完成的。我相信使用C你不會看到巨大的速度收益。
性能真的是一個問題嗎?這需要多長時間? – abarnert
如果這是一個製表符分隔的文件,它只有一列,因爲它沒有選項卡。 – abarnert
另外,你的awk腳本應該創建什麼?它絕對不會創建'file1.txt'等。 – abarnert