Ako generovať viac ako jeden list zo zoznamu, pomocou python funkcie

0

Otázka

Snažím sa, aby 8 puzzle problém riešiteľ pomocou rôznych algoritmov, ako BFS,DFS, A* pod. pomocou python. Pre tých, ktorí nie sú oboznámení s problémom, 8 puzzle problém je hra pozostáva z 3 riadky a 3 stĺpce. Môžete presunúť na prázdne dlaždice len vodorovne alebo zvisle, 0 predstavuje prázdne dlaždice. Vyzerá to, že tento (nemohol som si pridajte obrázky, vzhľadom na moje účty povesť.):

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 to, čo chcem funkcia "find_new_nodes(štát)" return 2 rôzne zoznamy, tak som si vybrať najsľubnejších uzol, v závislosti od algoritmus) a tak ďalej. Ale výkon môjho kód pozostáva z dvoch identických zoznamy.

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

Čo môžem urobiť, aby to vráti 2 rôzne zoznamy? Mojím cieľom je vrátiť všetky možné sa pohybuje v závislosti na tom, kde 0 je pomocou find_new_nodes funkciu. Ospravedlňujem sa, ak to je jednoduchá otázka, Toto je prvýkrát, čo projekt, to komplikované.

3

Najlepšiu odpoveď

1

Problém je, že swap_positions získa odkaz na globálne initial_state a nie klon to. Tak ako hovory do swap_positions mutovať rovnaké pole. Riešením by bolo klon pole na prvej výzvy: right = swap_positions(initial_state[:],0,1)

pravdepodobne lepšie riešenie pre swap_positions by tiež byť:

# 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

pozri aj tu

2021-11-22 13:05:24
0

Nemáte naozaj majú "dve identické zoznam", máte len jeden zoznam objektov, ktoré ste návrate dvakrát. Aby sa zabránilo úprava pôvodného zoznamu a tiež dve práce s rôzne zoznamy, mali by ste odovzdať kópie okolo.

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

Bočné poznámka 1: mám premenovali vášho vairable list na states, inak by to tieň postavený v zozname funkcie

Bočné poznámka 2: find_new_nodes nefunguje s parametrom, namiesto toho používa globálnom zozname. Zmenil som sa, že, príliš.

Bočné poznámka 3: Existujú rôzne spôsoby, ako vytvoriť kópiu (plytké) zoznam. Myslím, že list.copy() je najpodrobnejšie jeden. Môžete tiež použiť funkciu kopírovania modul, pomocou [:] alebo niečo iné.

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, po prvé, niektoré myšlienky...

  1. Pokúsiť sa nesmú používať "zoznam" ako variabilný, je to Python identifikátor na "zoznam" typu. Zdá sa, že ste vymedzením pojmu.

  2. Zvyčajne, je to zlý nápad, použiť globálne vars ako loc_of_zero.

O váš problém:

Som presvedčený, že problém je, že ste získali veľa odkazov na rovnakej premennej. Skúste sa vyhnúť. 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 iných jazykoch

Táto stránka je v iných jazykoch

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