簡體   English   中英

運行代碼時StopIteration不斷顯示

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM