Python: pop() возвращает py-список, а не мой объект

#python #python-3.x

#python #python-3.x

Вопрос:

Я пытаюсь закодировать упражнение для решения головоломки Queen (да, типичное, я знаю) на Python. Я создал класс с именем Queens для состояния доски, который учитывает длину каждой стороны и список ферзей, если таковые имеются.

В основной программе у меня вызывается list из Queens frontier , которые затем извлекаются один за другим. Однако результат, который я получаю от popping, похоже, имеет тип list , а не Queens такой, как ожидалось!

Что является причиной этого и как мне это исправить?

Фрагмент кода:

 from queens import Queens

def search(n, debug=False, max=6):
    frontier = [Queens(n, [])] # queue of states to explore
    while frontier != []:
        check = frontier.pop()
        print(type(check))
    if debug:
        print(str(numSolutions)   " | Checking:")
        print(check)
    v = check.validate()
    # EDIT: added more of the code; problem seems to arise here
    if v == 0:
        if debug:
            print("Solution!")
        numSolutions  = 1
        if n <= max:
            solutions.append(check)
    elif v > 0:
        if debug:
            print(str(v)   " more")
        frontier.append(check.branch())
    else:
        if debug:
            print("Invalid state")
        pass
  

ожидаемый результат:

 <class 'queens.Queens'>
  

фактический результат:

 <class 'queens.Queens'>
<class 'list'>
  

(да, оператор one type напечатал 2 строки)

РЕДАКТИРОВАТЬ: Поскольку, похоже, с основным кодом проблем нет, вот файл, в котором я определил класс:

 import array
import copy
class Queens:
    __slots__ = ["n", "qlist"]

    def __init__(self, n, qa=None):
        self.n = n # store for print function
        if qa == None:
            self.qlist = array.array("h")
        elif type(qa) == list:
            self.qlist = array.array("h", qa)
        else:
            assert type(qa) == array.array
            self.qlist = qa # list of positions for each line

    def __str__(self):
        out = ""
        for q in range(self.n):
            if q == 0:
                out  = "|"
            else:
                out  = "n|"
            for space in range(self.n):
                if q < len(self.qlist) and space == self.qlist[q]:
                    out  = "Q|"
                else:
                    out  = " |"
        return out

    def branch(self):
        out = []
        for x in range(self.n):
            if x not in self.qlist:
                qlist = copy.deepcopy(self.qlist)
                qlist.append(x)
                out.append(Queens(self.n, qlist))
        return out

    def validate(self):
        for y in range(len(self.qlist)):
            # don't need to check horizontal; 
            # data structure doesn't let you place them
            # don't need to check vertical;
            # branching eliminates those
            # check diagonals
            for y2 in range(len(self.qlist)):
                if y != y2:
                    expected = self.qlist[y] - y   y2
                    if 0 <= expected < self.n and self.qlist[y2] == expected:
                        return -1
                    expected = self.qlist[y]   y - y2
                    if 0 <= expected < self.n and self.qlist[y2] == expected:
                        return -1
        return self.n - len(self.qlist)

if __name__ == "__main__":
    q = Queens(4)
    print(q.validate())
    q = Queens(4, [0, 1, 2])
    print(q.validate())
  

Комментарии:

1. В опубликованном вами коде нет ничего плохого.

2. Можете ли вы опубликовать Queens?

3. python 3 или 2.x ?

4. Добавлен @denis_lor queens.py .

5. Мы не можем запустить этот код. Оба numSolutions и solutions не определены. Вам нужно попытаться создать фрагмент кода, который мы можем скопировать вставить с вашей ошибкой, потому что в настоящее время эта ошибка, вероятно, происходит где-то совершенно не там, где вы думаете, что это происходит.

Ответ №1:

Я понял это. Проблема возникла только после frontier.append(check.branch()) . branch() возвращает list из queens . Я думал, что добавляю несколько queens к frontier , но на самом деле я добавлял list of queens к frontier . Изменение append на extend решило проблему.

Ответ №2:

Когда вы добавляете к своему frontier результату .branch(..) и повторяете итерацию, вы получаете обратно массив (список). Который печатается после того, как цикл переходит к следующему шагу.

 def branch(self):
        out = []
        for x in range(self.n):
            if x not in self.qlist:
                qlist = copy.deepcopy(self.qlist)
                qlist.append(x)
                out.append(Queens(self.n, qlist))
        return out
  

Комментарии:

1. Что означает «Queens также является массивом»?