运行代码时StopIteration不断显示

时间:2018-07-11 11:29:00

标签: python python-3.x

我对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()

3 个答案:

答案 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