如何使用 python 函数从列表中生成多个列表

How to generate more than one list from a list, using python functions

我正在尝试使用不同的算法(例如 BFS、DFS、A* 等)使用 python 制作一个 8 拼图问题求解器。对于那些不熟悉问题的人来说,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(state)”return 2 个不同的列表,所以我可以根据算法选择最有希望的节点)和很快。但是我的代码的输出包含两个相同的列表。

这是我的输出: ([4, 0, 3, 1, 2, 5, 7, 8, 6], [4, 0, 3, 1, 2, 5, 7, 8, 6])

我该怎么做才能使它成为 return 2 个不同的列表?我的目标是 return 根据 0 的位置,使用 find_new_nodes 函数进行所有可能的移动。很抱歉,如果这是一个简单的问题,这是我第一次使项目如此复杂。

问题是 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

另见 here

您实际上并没有“两个相同的列表”,您只有一个要返回两次的列表对象。为避免修改原始列表以及两个使用不同列表的作品,您应该传递副本。

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:我已将您的变量 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])

好的,首先,一些想法...

  1. 尽量不要使用“list”作为变量,它是“list”类型的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