Jak generovat více než jeden seznam ze seznamu, pomocí funkce pythonu

0

Otázka

Snažím se, aby 8 puzzle řešitel problému pomocí různých algoritmů, jako BFS,DFS, A* atd. pomocí python. Pro ty, kteří nejsou obeznámeni s problémem, 8 problém puzzle je hra, se skládá ze 3 řádků a 3 sloupců. Můžete přesunout prázdný dlaždice pouze vodorovně nebo svisle, 0 představuje prázdné dlaždice. Vypadá to, že tento (nemohl jsem přidat obrázky, vzhledem k mé účty pověst.):

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))   

Problém mám, je, chci, funkce "find_new_nodes(stát)" return 2 různé seznamy, takže si můžu vybrat nejslibnější uzel, v závislosti na algoritmu) a tak dále. Ale výstup můj kód se skládá ze dvou totožných seznamů.

Tohle je můj výstup: ([4, 0, 3, 1, 2, 5, 7, 8, 6], [4, 0, 3, 1, 2, 5, 7, 8, 6])

Co mohu udělat, aby se to vrátit 2 různé seznamy? Mým cílem je vrátit všechny možné pohyby v závislosti na tom, kde 0 je pomocí find_new_nodes funkce. Omlouvám se, pokud to je jednoduchá otázka, To je můj první čas vytvoření projektu této komplikované.

3

Nejlepší odpověď

1

Problém je, že swap_positions získá odkaz na globální initial_state a ne klon. Takže obě volání swap_positions mutovat stejné pole. Řešení by bylo klon pole na první výzvu: right = swap_positions(initial_state[:],0,1)

asi lepší řešení pro swap_positions by také být:

# 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

viz také tady

2021-11-22 13:05:24
0

Ty opravdu nemají "dva identické seznam", budete mít jen jeden seznam objekt, který jste se vraceli dvakrát. Aby se zabránilo úpravy původního seznamu a také dva práci s různými seznamy, měli byste projít kopie kolem.

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))

Poznámka 1: jsem přejmenoval svůj vairable list k states, jinak by stín vestavěný seznam funkcí

Poznámka 2: find_new_nodes nefunguje s parametrem, místo toho použít globální seznam. Změnil jsem to taky.

Poznámka 3: Tam jsou různé způsoby, jak vytvořit kopii (mělké) seznam. Myslím, že list.copy() je nejvíce upovídaný. Můžete také použít kopii modul, použijte [:] nebo něco jiného.

Výstup:

([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

Ok, v první řadě, některé myšlenky...

  1. Snažte se nepoužívat "seznam" jako proměnnou, je to Python identifikátor pro "seznamu" typ. Zdá se, že jste předefinování pojmu.

  2. Obvykle je to špatný nápad používat globální vars jako loc_of_zero.

O váš problém:

Jsem přesvědčen, že problém je, že jsou stále hodně odkazů na stejnou proměnnou. Zkuste, aby se zabránilo to. Jeden nápad:

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

V jiných jazycích

Tato stránka je v jiných jazycích

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