如何使用 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])
好的,首先,一些想法...
尽量不要使用“list”作为变量,它是“list”类型的Python标识符。看来你是在重新定义这个词。
通常,使用全局变量是个坏主意,例如 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
我正在尝试使用不同的算法(例如 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])
好的,首先,一些想法...
尽量不要使用“list”作为变量,它是“list”类型的Python标识符。看来你是在重新定义这个词。
通常,使用全局变量是个坏主意,例如 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