[英]Error in looping through a text file in python
我試圖循環文本文件並應用一些邏輯,但我無法循環文本文件。 所以目前我有一個文本文件,結構如下:
--- section1 ---
"a","b","c"
"d","e","f"
--- section2 ---
"1","2","3"
"4","5","6"
--- section3 ---
"12","12","12"
"11","11","11"
我試圖過濾出包含'---'的第一行,並將下面的行轉換為json,直到下一行'---'行出現在文本文檔中。
但是我得到了這個錯誤“ fields1 = next(file).split(',')StopIteration
with open(fileName,'r') as file:
for line in file:
if line.startswith('-') and 'section1' in line:
while '---' not in next(file):
fields1 = next(file).split(',')
for x in range(0,len(fields1)):
testarr.append({
config.get('test','test'): fields1[x]
})
with open(test_dir,'w') as test_file:
json.dump(testarr, test_file)
知道為什么我的代碼不起作用或我如何解決錯誤?
看起來你是在大量過度復雜的事情。 我想到的內部while
循環中的next
內部正在掀起外部for
循環,但這無論如何都是不必要的。 你已經在線上循環了; 選擇你想要的,然后在你完成后退出。
with open(fileName,'r') as inputfile:
for line in inputfile:
if line.startswith('-') and 'section1' in line:
continue
elif line.startswith('-'):
break
else:
testarr.append({config.get('test', 'test'): x
for x in line.split(',')})
with open(test_dir,'w') as test_file:
json.dump(testarr, test_file)
我希望我得到了正確的append
權,因為我還想向您展示如何更優雅地映射分割字段,但我不確定我是否完全理解您的原始代碼所做的事情。 (我猜你會想要在分割它之前修剪\\n
,然后再切割它。另外,我想你想要修改每個值周圍的引號x.strip('"') for x in line.rstrip('\\n').split(',')
)
我還將file
重命名為inputfile
以避免與保留關鍵字file
發生沖突。
如果你想編寫更多文件,基本上,在循環中添加更多狀態,並將寫片段移回循環內。 我不是特別想解釋它是如何等同於狀態機的,但它應該不難理解:有兩個狀態,你正在跳過或收集; 為了擴展它,在向后翻轉時為邊界添加一個狀態,在此處寫出收集的數據並將收集的行重新初始化為無。
你錯誤的原因是,你可以通過調用濫用文件對象都能運行next
就可以了一倍,而像你想象的。 每次調用next
都會獲得一行並返回它。 因此, while '---' not in next(file): fields1 = next(file).split(',')
獲取一行,檢查它是否為---
,然后獲取另一行並嘗試解析它。 這意味着你可以跳過包含---
的行,讓它在next
。 在這種情況下,您將在找到要查找的行之前到達文件的末尾。 StopIteration
是迭代器通常表明其輸入已經耗盡的方式。
您可能希望在代碼中解決其他幾個問題:
for
循環中時,在文件生成器上使用next
可能會導致未定義的行為。 這次你可能會僥幸成功,但這並不是一般的好習慣。 順便說一下,你擺脫它的主要原因可能是,一旦觸發while
,你永遠不會真正將控制權返回給for
循環,而且在這方面文件並不是特別寬松。 with
轉儲數據到一個文件是內部的while
循環。 這意味着您使用'w'
權限打開的文件將在while
每次迭代(即文件中的每一行)中被截斷。 隨着數組的增長,輸出實際上看起來很好,但是你可能希望將其移出內部循環。 最簡單的解決方案是在兩個循環中重寫代碼:一個用於查找您關注的部分的開始,另一個用於處理它直到找到結束。
像這樣的東西:
test_arr = []
with open(fileName, 'r') as file:
for line in file:
if line.startswith('---') and 'section1' in line:
break
for line in file:
if '---' in line:
break
fields1 = line.split(',')
for item in fields1:
testarr.append({config.get('test','test'): item})
with open(test_dir,'w') as test_file:
json.dump(testarr, test_file)
編輯:
考慮到@ tripleee的建議,我已經刪除了起始行的正則表達式檢查。 雖然正則表達式為查找特定模式提供了極高的精度和靈活性,但對於這個例子來說這實在是太過分了。 我想指出的是,如果你正在尋找除section1之外的部分,或者如果section1出現在帶有破折號的其他行之后,你絕對需要這種雙循環方法。 其他答案中的單循環解決方案不適用於非平凡的情況。
當迭代器用完時, next()
引發一個StopIteration
異常。 換句話說,你的代碼到達文件的末尾,然后再次調用next()
,並且沒有更多內容可以返回,因此它會引發該異常。
至於如何解決你的問題,我想這可能是你想要的:
with open(fileName, 'r') as file:
for line in file:
if line.startswith('---'):
if 'section1' in line:
continue
else:
break
fields1 = line.split(',')
for x in range(len(fields1)):
testarr.append({
config.get('test', 'test'): fields1[x]
})
with open(test_dir, 'w') as test_file:
json.dump(testarr, test_file)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.