Проблема с циклом for в python - PullRequest
1 голос
/ 15 марта 2010

Предполагается, что этот код сможет сортировать элементы в self.array в соответствии с порядком символов в self.order. Метод sort работает должным образом до третьей итерации, пока по какой-то причине цикл for, кажется, не повторяется бесконечно. Что здесь происходит?

Edit: я делаю свою собственную функцию сортировки, потому что это бонусная часть моего Python-задания.

class sorting_class:
    def __init__(self):
        self.array = ['ca', 'bd', 'ac', 'ab'] #An array of strings
        self.arrayt = []
        self.globali = 0
        self.globalii = 0
        self.order = ['a', 'b', 'c', 'd'] #Order of characters
        self.orderi = 0
        self.carry = []
        self.leave = []
        self.sortedlist = []
    def sort(self):
        for arrayi in self.arrayt:  #This should only loop for the number items in self.arrayt. However, the third time this is run it seems to loop indefinitely. 
            print ('run', arrayi)   #Shows the problem
            if self.order[self.orderi] == arrayi[self.globali]:
                self.carry.append(arrayi)
            else:
                if self.globali != 0:
                    self.leave.append(arrayi)
    def srt(self):
        self.arrayt = self.array
        my.sort() #First this runs the first time.
        while len(self.sortedlist) != len(self.array):
            if len(self.carry) == 1:
                self.sortedlist.append(self.carry)
                self.arrayt = self.leave
                self.leave = []
                self.carry = []
                self.globali = 1
                self.orderi = 0
                my.sort()
            elif len(self.carry) == 0:
                if len(self.leave) != 0: #Because nothing matches 'aa' during the second iteration, this code runs the third time"
                    self.arrayt = self.leave
                    self.globali = 1
                    self.orderi += 1
                    my.sort()
                else:
                    self.arrayt = self.array
                    self.globalii += 1
                    self.orderi = self.globalii
                    self.globali = 0
                    my.sort()
                    self.orderi = 0
            else: #This is what runs the second time.
                self.arrayt = self.carry
                self.carry = []
                self.globali += 1
                my.sort()
my = sorting_class()  
my.srt()

Ответы [ 3 ]

1 голос
/ 15 марта 2010

У вас есть self.arrayt = self.leave, что делает arrayt ссылкой на тот же массив, что и leave (это не копия содержимого !!!), затем в цикле for arrayi in self.arrayt: вы создайте self.leave.append(arrayi) - что увеличивает self.leave, что является еще одним названием для самого списка self.arrayt, на который вы зацикливаетесь. Добавление к списку, по которому вы зацикливаетесь, - хороший рецепт для бесконечных циклов.

Это всего лишь один из симптомов неразрывной путаницы в этом коде. Я рекомендую вам выполнить сортировку с помощью встроенного метода sort и потратить энергию на определение правильной функции извлечения ключа key=, чтобы сортировать вещи именно так, как вы хотите - много больше продуктивное использование вашего времени.

1 голос
/ 15 марта 2010

Алекс, который упоминает экстрактор ключей, достаточно тривиален для включения лямбда-функции

>>> array = ['ca', 'bd', 'ac', 'ab']
>>> order = ['a', 'b', 'c', 'd']
>>> sorted(array, key=lambda v:map(order.index,v))
['ab', 'ac', 'bd', 'ca']

>>> order = ['b', 'a', 'c', 'd']
>>> sorted(array, key=lambda v:map(order.index,v))
['bd', 'ab', 'ac', 'ca']

>>> order = ['d', 'c', 'b', 'a']
>>> sorted(array, key=lambda v:map(order.index,v))
['ca', 'bd', 'ac', 'ab']

Посмотрим, как это работает:

map вызывает метод order.index для каждого элемента в v и использует эти возвращаемые значения для создания списка.
v будет одним из элементов array

>>> order = ['a', 'b', 'c', 'd']
>>> map(order.index,array[0])
[2, 0]
>>> map(order.index,array[1])
[1, 3]
>>> map(order.index,array[2])
[0, 2]
>>> map(order.index,array[3])
[0, 1]

Функция предоставляется как key= для сортировки, поэтому внутренние списки сортируются вместо строк.

1 голос
/ 15 марта 2010

Во время третьего прохода вашего цикла вы добавляете новые элементы в список, который вы перебираете, поэтому вы никогда не можете выйти из цикла:
self.arrayt = self.leave - это назначение приводит к тому, что self.leave.append(arrayi) будет добавлять элементы в список, к которому относится self.arrayt.

В общем, вы можете подумать о создании копий списков, а не просто о назначении разных переменных / членов одним и тем же экземплярам списков.

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