【问题标题】:How to generate more than one list from a list, using python functions如何使用python函数从列表中生成多个列表
【发布时间】:2021-11-22 12:52:37
【问题描述】:

我正在尝试使用 python 使用不同的算法(例如 BFS、DFS、A* 等)制作一个 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)”返回2个不同的列表,所以我可以选择最有希望的节点,具体取决于算法)等等。但是我的代码输出包含两个相同的列表。

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

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

【问题讨论】:

    标签: python algorithm artificial-intelligence


    【解决方案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
    

    另见here

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        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 
        

        【讨论】:

          猜你喜欢
          • 2016-04-28
          • 1970-01-01
          • 2019-05-05
          • 1970-01-01
          • 2013-05-28
          • 2011-05-24
          • 1970-01-01
          • 2021-04-03
          • 2021-04-26
          相关资源
          最近更新 更多