2010-05-13 5 views
0

두 개의 클래스가 포함 된 스크립트가 있습니다. (나는 분명히 내가 다루고있는 오류와 관련이 있다고 생각지 않는 많은 것들을 삭제하고있다.) 궁극적 인 작업은 내가 this 질문에서 언급했듯이 의사 결정 트리를 만드는 것이다.python3에서 클래스의 목록에 행을 추가 할 때 무한 루프

불행히도 무한 루프가 발생하며 그 이유를 파악하는 데 어려움이 있습니다. 내가 엮어내는 코드 라인을 확인했지만 반복자와 내가 추가 할 목록이 다른 객체라고 생각했을 것입니다. 목록의 .append 기능에 대한 부작용이 있습니까? 아니면 다른 눈에 띄게 실수를 저지르고 있습니까?

class Dataset: 
    individuals = [] #Becomes a list of dictionaries, in which each dictionary is a row from the CSV with the headers as keys 
    def field_set(self): #Returns a list of the fields in individuals[] that can be used to split the data (i.e. have more than one value amongst the individuals 
    def classified(self, predicted_value): #Returns True if all the individuals have the same value for predicted_value 
    def fields_exhausted(self, predicted_value): #Returns True if all the individuals are identical except for predicted_value 
    def lowest_entropy_value(self, predicted_value): #Returns the field that will reduce <a href="http://en.wikipedia.org/wiki/Entropy_%28information_theory%29">entropy</a> the most 
    def __init__(self, individuals=[]): 

class Node: 
    ds = Dataset() #The data that is associated with this Node 
    links = [] #List of Nodes, the offspring Nodes of this node 
    level = 0 #Tree depth of this Node 
    split_value = '' #Field used to split out this Node from the parent node 
    node_value = '' #Value used to split out this Node from the parent Node 

    def split_dataset(self, split_value): #Splits the dataset into a series of smaller datasets, each of which has a unique value for split_value. Then creates subnodes to store these datasets. 
     fields = [] #List of options for split_value amongst the individuals 
     datasets = {} #Dictionary of Datasets, each one with a value from fields[] as its key 
     for field in self.ds.field_set()[split_value]: #Populates the keys of fields[] 
      fields.append(field) 
      datasets[field] = Dataset() 
     for i in self.ds.individuals: #Adds individuals to the datasets.dataset that matches their result for split_value 
      datasets[i[split_value]].individuals.append(i) #<---Causes an infinite loop on the second hit 
     for field in fields: #Creates subnodes from each of the datasets.Dataset options 
      self.add_subnode(datasets[field],split_value,field) 

    def add_subnode(self, dataset, split_value='', node_value=''): 
    def __init__(self, level, dataset=Dataset()): 

내 초기화 코드는 현재 :

if __name__ == '__main__': 
    filename = (sys.argv[1]) #Takes in a CSV file 
    predicted_value = "# class" #Identifies the field from the CSV file that should be predicted 
    base_dataset = parse_csv(filename) #Turns the CSV file into a list of lists 
    parsed_dataset = individual_list(base_dataset) #Turns the list of lists into a list of dictionaries 
    root = Node(0, Dataset(parsed_dataset)) #Creates a root node, passing it the full dataset 
    root.split_dataset(root.ds.lowest_entropy_value(predicted_value)) #Performs the first split, creating multiple subnodes 
    n = root.links[0] 
    n.split_dataset(n.ds.lowest_entropy_value(predicted_value)) #Attempts to split the first subnode. 

답변

4
class Dataset: 
    individuals = [] 

의심. Dataset의 모든 인스턴스에서 정적 멤버 목록을 공유하지 않으려면 그렇게해서는 안됩니다. __init__self.individuals= something을 설정하는 경우 individuals도 여기에 설정할 필요가 없습니다.

def __init__(self, individuals=[]): 

여전히 의심 스럽다. individuals 인수를 self.individuals에 할당하고 있습니까? 그렇다면 함수 정의시 작성된 동일한 individuals 목록을 기본 인수로 작성된 Dataset에 지정합니다. Dataset의 목록에 항목을 추가하면 명시적인 individuals 인수없이 작성된 다른 모든 항목도 해당 항목을 가져옵니다. 마찬가지로

: 명시 적 dataset 인수없이 생성

class Node: 
    def __init__(self, level, dataset=Dataset()): 

모든 Node의 정확한 동일한 기본 Dataset 인스턴스를 받게됩니다.

이것은 mutable default argument problem이며 생성되는 파괴적 반복의 종류가 무한 루프를 유발할 가능성이 높습니다.

+0

+1 좋은 답변입니다. –

4

나는 당신이 당신이 전에 크기가 증가하는 원인이 반복되는 동일한 목록에 추가하는 것으로 의심 iterator는 그것의 끝까지 도달 할 수있다. 대신 목록의 사본을 반복하십시오 :

for i in list(self.ds.individuals): 
    datasets[i[split_value]].individuals.append(i) 
+0

파이썬 3에 여전히 슬라이스 연산자가 있습니까? IE for i in self.ds.individuals [:] : other_code ? – mcpeterson

+0

@McPeterson, 조각은 여전히 ​​Python3에서 작동합니다. –