[英]StopIteration keeps showing randomly when running code
我對Python還是很陌生,我試圖將一個看起來確實有效的小程序組合在一起,但是在運行代碼時,我經常會遇到以下錯誤。
最終目標比當前代碼稍微復雜一些,但是其思想是程序從2個單獨的CSV文件讀取,從每個CSV文件中選擇一個隨機行,然后將這些行中的特定值連接起來並打印結果。
看到錯誤:
Traceback (most recent call last):
File ".\SimulationScript.py", line 57, in <module>
counter(10)
File ".\SimulationScript.py", line 45, in counter
indicatorDefinition(indicator_file)
File ".\SimulationScript.py", line 17, in indicatorDefinition
chosen_row = next(row for row_number, row in enumerate(reader)
StopIteration
碼:
from sys import argv
import random
import csv
script, file1, file2 = argv
f1 = ''
f2 = ''
def iDefinition(i):
with open(i) as file:
lines = sum(1 for line in file)
line_number = random.randrange(lines)
with open(i) as file:
reader = csv.DictReader(file)
chosen_row = next(row for row_number, row in enumerate(reader)
if row_number == line_number)
global f1
f1 = chosen_row['field_1']+'":"'+chosen_row['value_1']+'"'
def nDefinition(n):
with open(n) as file:
lines = sum(1 for line in file)
line_number = random.randrange(lines)
with open(n) as file:
reader = csv.DictReader(file)
chosen_row = next(row for row_number, row in enumerate(reader)
if row_number == line_number)
global f2
f2 = '"code":"'+chosen_row['Node code']+'","'
def counter():
count = 0
while count < 6:
nDefinition(file2)
iDefinition(file1)
print(f2+f1)
count += 1
counter()
當完全迭代可迭代對象時,接下來將拋出StopIterationError。 這應該不是隨機發生的,但是每次在迭代過程遍歷整個可迭代對象之后運行代碼。
您可以為其創建一個try / except塊,或者使用for循環而不是next循環。 (Python中的for循環在完成循環后會自動捕獲並“忽略” stopiteration錯誤)。
row for row_number, row in enumerate(reader):
if row_number == line_number:
chosen_row = row
如摘自https://docs.python.org/3/glossary.html#term-iterator :
如果沒有更多數據可用,則會引發StopIteration異常。 此時,迭代器對象已用盡,對其
__next__()
方法的任何進一步調用都只會再次引發StopIteration。
enumerate()
返回一個Iterator對象,因此是上述情況。 大概您的腳本已到達CSV的最后一行,並且對next()
調用要求Iterator返回另一個(當然,這是不可能的)。
如預期的那樣,您可能希望將表達式包含在try-except塊中,捕獲StopIteration異常,然后繼續執行您的方法。
另一種選擇是使用一個for循環,該循環在最后一個元素被迭代之后就停止了。 通常僅在需要控制何時提取下一個元素的時間時才使用next()
調用,而不是如果您要一次性遍歷所有元素時則不使用。
如前所述StopIteration
在嘗試使用窮盡的可迭代對象中的元素時引發。
it = iter([1, 2])
next(it)
# 1
next(it)
# 2
next(it)
# raises StopIteration as nothing to return
# however you can use the default argument to return a default value when exhausted
# next(it, 'cabbage!')
# cabbage!
但是,由於您只想從文件中隨機抽取一行,而不是對行進行計數並選擇行號,然后掃描文件並提取該行,因此可以使用帶有隨機鍵的min
並將其組合通過,例如:
import heapq, random
with open('your_file') as fin:
random_line = min(fin, key=lambda L: random.random())
如果要取大於1,則可以這樣使用heapq
:
with open('your_file') as fin:
random_50 = heapq.nlargest(50, fin, key=lambda L: random.random())
如果這些文件不會消耗系統內存,而您又想占用大量隨機行,則可以將它們加載到list
,然后使用random.choice
,例如:
with open('your_file') as fin:
data = list(fin)
r1 = random.choice(data)
r2 = random.choice(data)
# ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.