Цикл For не обновляет свой диапазон при обновлении списка в Python - PullRequest
0 голосов
/ 04 ноября 2018

В рамках небольшого проекта, использующего объектно-ориентированное программирование на Python. Я попытался сделать простую программу настройки / моделирования для вычислительного кластера. Кластер состоит из набора стоек, и каждая стойка состоит из 12 узлов каждая. Я почти закончил программу, хотя изо всех сил пытаюсь понять, почему это происходит и как ее решить.

Вся программа охватывает три класса: узел, стойку и кластер.

То, что я пытаюсь сделать здесь, - это создать метод, который проверяет, заполнена ли стойка (при условии, что она содержит 12 узлов), и, если это так, создайте новый экземпляр стойки, а затем заполните новый экземпляр стойки узлы.

Это соответствующий код для кластера

class Cluster:
    def __init__(self, nodesPerRack, racks=[]):
        self.nodesPerRack = nodesPerRack
        self.racks = racks

    def addNode(self, node):
        if len(self.racks) == 0:
            newRack = Rack()
            self.racks.append(newRack)
            print(len(self.racks))

        for i in range(len(self.racks)):
            if self.racks[i].getNodes() < self.nodesPerRack:
                print("IM ADDING TO A RACK")

                self.racks[i].settInn(node)

            elif self.racks[i].getNodes() >= self.nodesPerRack:
                print("New rack is being made")
                newRack = Rack()

                newRack.insertInto(node)

                self.racks.append(newRack)

Если программа запущена, она, похоже, ничего не делает, и я подозреваю, что она генерирует бесчисленные экземпляры Rack или периодически проверяет, есть ли в стойке место (таким образом потребляя кучу оперативной памяти?)

Я пробовал несколько методов, и я начинаю подозревать, что диапазон, который он перебирает, не обновляется, он зависает, даже если добавлен новый элемент Rack, что должно обновить следующее утверждение

for i in range(len(self.racks)):

Как сделать так, чтобы цикл for обновлял свой диапазон? Я попытался с помощью следующего метода, используя цикл while

i = 0
while i < self.nodesPerRack:
    do something
i += 1

По-прежнему возникает та же проблема, что и в цикле for.

Дополнительно здесь приведены соответствующие детали для Rack

class Rack: 
    def __init__(self, nodes=[]):
        self.nodes = nodes

    def addTo(self, node):
        self.nodes.append(node)

и класс для Узла

class Node:
    def __init__(self, minne, antPros):
        self.minne = minne
        self.antpros = antPros

Вот код, который я использовал для запуска теста

from node import Node
from rack import Rack
from cluster import Cluster

cluster = Cluster(12)

for i in range(0,650):
    newNode = Node(64,1)
    cluster.addNode(newNode)

for i in range(0,16):
    newNode = Node(1024, 2)
    cluster.addNode(newNode)

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

В дополнение к ответу Мартин, я не уверен, что

self.racks[i].getNodes()

возвращает число узлов по имени метода. Если он их возвращает, то мой ответ не актуален.

0 голосов
/ 04 ноября 2018

range(len(self.racks)) принимает длину один раз при выполнении этого выражения. Цикл for не переоценивает это выражение каждую итерацию.

Вы можете избежать всей проблемы, просто зацикливаясь на самом списке:

for rack in self.racks:

и используйте rack вместо self.racks[i]. Итератор, созданный для объекта списка, остается подключенным к списку, и каждый раз, когда вы запрашиваете следующее значение, он повторно проверяет длину. Это означает, что цикл for над списком, который расширяется в цикле, будет повторять и дополнительные элементы:

>>> l = [42, 81]
>>> for i in l:
...     print(i)
...     if i == 42:
...         l.append(117)
...
42
81
117

В других случаях вы можете использовать цикл while, который каждый раз проверяет счетчик длины:

i = 0
while i < len(self.racks):
    # ...
    i += 1

while выполняет переоценку выражения на каждой итерации:

>>> l = [42, 81]
>>> i = 0
>>> while i < len(l):
...     print(l[i])
...     if l[i] == 42:
...         l.append(117)
...     i += 1
...
42
81
117

Цикл while является более громоздким для этой задачи, так как теперь вы должны вручную поддерживать счетчик, индексировать в свой список self.racks каждый раз, и легко забыть или пропустить i += 1 в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...