我对Python还是很陌生,我正在尝试编写一个看起来确实有效的小程序,但是在运行代码时,我经常会遇到以下错误。
最终目标比当前代码稍微复杂一些,但是想法是程序从2个单独的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()
答案 0 :(得分:0)
StopIterationError将由next抛出。这应该不是随机发生的,但是每次在迭代过程遍历整个可迭代对象之后运行代码。
您可以为其创建一个try / except块,或者使用for循环代替next。 (Python中的for循环在完成循环后会自动捕获并“忽略” stopiteration错误)。
row for row_number, row in enumerate(reader):
if row_number == line_number:
chosen_row = row
答案 1 :(得分:0)
摘自https://docs.python.org/3/glossary.html#term-iterator:
当没有更多数据可用时,将引发StopIteration异常。此时,迭代器对象已用尽,对其
__next__()
方法的任何进一步调用只会再次引发StopIteration。
enumerate()
返回一个Iterator对象,因此是上述情况。大概您的脚本已到达CSV的最后一行,而您对next()
的调用要求Iterator返回另一个(当然,这是不可能的)。
由于预期会出现此异常,因此您可能希望将表达式包含在try-except块中,捕获StopIteration异常,然后继续执行方法。
另一种选择是使用for循环,该循环仅在最后一个元素被迭代后停止。 next()
调用通常仅在您需要控制何时提取下一个元素时使用,而在您想要一次遍历所有内容时不使用。
答案 2 :(得分:0)
如上所述-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
中,然后使用{{1} },例如:
random.choice