Как создать более одного списка из списка, используя функции python

0

Вопрос

Я пытаюсь создать решатель задач из 8 головоломок, используя различные алгоритмы,такие как BFS, DFS, A* и т.д., Используя python. Для тех, кто не знаком с проблемой, 8 задач-головоломок-это игра, состоящая из 3 строк и 3 столбцов. Вы можете перемещать пустую плитку только по горизонтали или вертикали, 0 представляет пустую плитку. Это выглядит так (я не смог добавить изображения из-за репутации моих аккаунтов).:

https://miro.medium.com/max/679/1*yekmcvT48y6mB8dIcK967Q.png

initial_state = [0,1,3,4,2,5,7,8,6]
goal_state = [1,2,3,4,5,6,7,8,0]
    
def find_zero(state):
       global loc_of_zero
       loc_of_zero = (state.index(0))


def swap_positions(list, pos1, pos2):
       first = list.pop(pos1)
       second = list.pop(pos2-1)

       list.insert(pos1,second)
       list.insert(pos2,first)
       return list

 def find_new_nodes(state):
      if loc_of_zero == 0:
         right = swap_positions(initial_state,0,1)
         left = swap_positions(initial_state,0,3)
         return(right,left)




find_zero(initial_state)
print(find_new_nodes(initial_state))   

Проблема у меня такая, я хочу, чтобы функция "find_new_nodes(состояние)" возвращала 2 разных списка, чтобы я мог выбрать наиболее перспективный узел, в зависимости от алгоритма) и так далее. Но вывод моего кода состоит из двух одинаковых списков.

Это мой результат: ([4, 0, 3, 1, 2, 5, 7, 8, 6], [4, 0, 3, 1, 2, 5, 7, 8, 6])

Что я могу сделать, чтобы он вернул 2 разных списка? Моя цель-вернуть все возможные ходы в зависимости от того, где находится 0, используя функцию find_new_nodes. Извините, если это простой вопрос, но я впервые делаю проект таким сложным.

3

Лучший ответ

1

Проблема в том, что swap_positions получает ссылку на глобальную initial_state и не его клон. Поэтому оба звонка в swap_positions мутируйте один и тот же массив. Решением было бы клонировать массив при первом вызове: right = swap_positions(initial_state[:],0,1)

вероятно, лучшее решение для swap_positions также было бы:

# please do not name variables same as builtin names
def swap_positions(lis, pos1, pos2):
       # create a new tuple of both elements and destruct it directly
       lis[pos1], lis[pos2] = lis[pos2], lis[pos1]
       return lis

смотрите также здесь

2021-11-22 13:05:24
0

На самом деле у вас нет "двух одинаковых списков", у вас есть только один объект списка, который вы возвращаете дважды. Чтобы избежать изменения исходного списка, а также работы с двумя разными списками, вам следует передавать копии по кругу.

initial_state = [0,1,3,4,2,5,7,8,6]
goal_state = [1,2,3,4,5,6,7,8,0]

def find_zero(state):
    global loc_of_zero
    loc_of_zero = (state.index(0))


def swap_positions(states, pos1, pos2):
    first = states.pop(pos1)
    second = states.pop(pos2-1)

    states.insert(pos1,second)
    states.insert(pos2,first)
    return states

def find_new_nodes(states):
    if loc_of_zero == 0:
        right = swap_positions(states.copy(),0,1) # pass around a copy
        left = swap_positions(states.copy(),0,3) # pass around a copy
        return(right,left)

find_zero(initial_state)
print(find_new_nodes(initial_state))

Примечание 1: Я переименовал ваш vairable list Для states, в противном случае это затенит встроенную функцию списка

Примечание 2: find_new_nodes не работал с параметром, вместо этого он использовал глобальный список. Это я тоже изменил.

Примечание 3: Существуют различные способы создания копии вашего (неглубокого) списка. Я думаю list.copy() это самый многословный из них. Вы также можете использовать модуль копирования, использовать [:] или что-то еще.

Выход:

([1, 0, 3, 4, 2, 5, 7, 8, 6], [4, 1, 3, 0, 2, 5, 7, 8, 6])
2021-11-22 13:06:24
0

Ладно, прежде всего, кое-какие мысли...

  1. Старайтесь не использовать "список" в качестве переменной, это идентификатор Python для типа "список". Похоже, вы переосмысливаете этот термин.

  2. Обычно использовать глобальные переменные, такие как loc_of_zero, - плохая идея.

О вашей проблеме:

Я считаю, что проблема в том, что вы получаете много ссылок на одну и ту же переменную. Постарайтесь избежать этого. Одна идея:

from copy import deepcopy
def swap_positions(list0, pos1, pos2): 
    list1 = deepcopy(list0) 
    first = list1.pop(pos1) 
    second = list1.pop(pos2-1) 

    list1.insert(pos1,second) 
    list1.insert(pos2,first) 
    return list1 
2021-11-22 13:12:44

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................