Python 无法比较字符串

Python fails to compare strings

我在 python 中遇到了一个奇怪的问题。我有一个迷宫,x 代表墙,g 是目标,s 是起点,数字是将您从一个数字带到另一个数字的门户(例如,如果您继续 2 中的一个,它将把您带到其他 2).

xxxxxxxxxxxxxxxxxxxx
x2                 x
x       xxx        x
x   1   x xxxxx    x
x   s     x        x
x       x x  xxxxxxx
x  xx xxxxx        x
x      x      g    x
x   1  x  2        x
xxxxxxxxxxxxxxxxxxxx

我正在尝试找到所有门户并将它们放入一个数组中。到目前为止一切正常,程序找到了所有四个门户。

import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()
file = filedialog.askopenfilename()

def readMazeToArray(path):
    with open(path) as f:
        return [list(line.strip()) for line in f]

maze = readMazeToArray(file)

def findPortals(maze):
    portals = []
    for i in range(0, len(maze)):
        for j in range(0, len(maze[i])):
            if (maze[i][j] != 'g' and maze[i][j] != 's' 
            and maze[i][j] != 'x' and maze[i][j] != ' '):
                portals.append([i, j])
    return portals

从那以后,事情变得有点奇怪了。这是似乎无法正常工作的代码:

def portalHeuristic(maze, x1, x2, y1, y2):
    portals = findPortals(maze)
    for portal in portals:
        for i in range(0, len(maze)):
            for j in range(0, len(maze[i])):

                if maze[i][j] == maze[portal[0]][portal[1]] 
                and (portal[0] != i or portal[1] != j):

                     return abs(x1 - portal[0]) + abs(y1 - portal[1]) 
                            + abs(x2 - i) + abs(y2 - j))

        print(maze[i][j] == maze[portal[0]][portal[1]])

        print("x1 = ", x1, ", y1 = ", y1, ", portal0 = ", 
        portal[0], ", portal1 = ", portal[1], ", x2 = ",
        x2, ", y2 = ", y2, ", i = ",  i, ", j = ", j)


portalHeuristic(maze, 4, 4, 7, 14)

portalHeuristic 基本上做的是它现在遍历一个又一个门户寻找与当前门户相同的符号 (maze[i][j] == maze[portal[0]][portal[1]]),但确保它没有找到当前门户本身通过比较当前门户的坐标和它找到的具有相同符号/数字 (portal[0] != i or portal[1] != j) 的门户的坐标。最终它会计算出起点和当前 Portal 及其孪生 Portal 和目标之间的距离。

但似乎 maze[i][j] == maze[portal[0]][portal[1]] 似乎不起作用,因为我的程序总是告诉我在 i=9,j=19 处找到了另一个门户,无论是哪个门户。奇怪的是,如果我自己测试字符串的相等性 python 意识到它总是错误的。我究竟做错了什么?我现在已经花了 3 个多小时寻找错误,但我似乎无法找到它。也许这是一个非常愚蠢的人? 另外,请忍受我糟糕的代码。我刚开始 python.

在您的 findPortal 方法中,您创建一个列表,其中将包含您的门户坐标。最后它应该是这样的(它是随机数):portals = [[2,5], [5,1], ...]

在您的 portalHeuristic 中,在您的条件 maze[i][j] == maze[portal[0]][portal[1]]portal[0] = [2,5]portal[1] = [5,1] 中。所以基本上,你正在做 maze[i][j] == maze[[2,5]][[5,1]] ,奇怪的是 python 没有引发异常。所以这就是为什么你的条件总是错误的。


话虽如此,您的代码效率很低。您遍历迷宫以找到入口,然后在迷宫中再次重复(因为您有 4 个入口,所以重复 4 次)。在搜索门户时直接将它们配对怎么样?你可以使用一个字典,键是你的门户号码(这里是 1 或 2),它甚至可以是字符“1”或“2”而不是数字,值将是一个包含 2 个元素的列表,每个元素都是传送门的坐标。

def findPortals(maze):
    portals = {} #That's a dict
    for i in range(0, len(maze)):
        for j in range(0, len(maze[i])):
            if (maze[i][j] != 'g' and maze[i][j] != 's' 
            and maze[i][j] != 'x' and maze[i][j] != ' '):
                if maze[i][j] in portals:
                    # We already have one, put the other
                    portals[maze[i][j]].append([i,j])
                else:
                    # It is the first one
                    portals[maze[i][j]] = [[i,j]]
    return portals

祝你好运!


您可以将字典视为一个列表,其中的键不必是数字,也不必是连续的(如果您的列表中有 5 个项目,则可以使用 list[0]、list [1], 等..). 因此,如果您想访问字典中的某个项目,只需传递密钥即可。在您的启发式方法中,您似乎想要找到 [x1, y1] 与列表中发现的第一个门户之间的距离,并将其与相关门户与 [x2, y2] 之间的其他距离相加。这有点太具体了,您可以指定要检查的门户(例如“1”或“2”)。

因此你的函数变成:

def portalHeuristic(portals, x1, y1, x2, y2, portal_number):
    # Check if the portal exist in you list
    if portal_number not in portals:
        print("This portal number is not in the list")
        return
    # This line is a shortcut. Since we know that portals[x] is a list of 
    # two elements (coordinates of both portals with the same number), 
    # you can assign the first element with first_portal and the second element 
    # with second_portal.
    first_portal, second_portal = portals[portal_number]
    return abs(x1 - first_portal[0]) + abs(y1 - first_portal[1]) 
                        + abs(x2 - second_portal[0]) + abs(y2 - second_portal[1]))

不要忘记您的键是字符(“1”或“2”)而不是 1 或 2(整数)。 portal_number 应该是一个字符。

一旦你熟悉了列表理解就很难写出for循环

但也许您可以从我的示例列表中逆向计算 http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/

我在 listcomps 中添加了换行符和前导空格以提高可读性

您还应该看到 enumerate 在这些类型的索引循环中对元素测试很有帮助

maze = ['xxxxxxxxxxxxxxxxxxxx',
 'x2                 x',
 'x       xxx        x',
 'x   1   x xxxxx    x',
 'x   s     x        x',
 'x       x x  xxxxxxx',
 'x  xx xxxxx        x',
 'x      x      g    x',
 'x   1  x  2        x',
 'xxxxxxxxxxxxxxxxxxxx']

prtls = [[c, (j, k)]
         for k, ln in enumerate(maze)
            for j, c in enumerate(ln) if c.isdigit()]
prtls
Out[206]: [['2', (1, 1)], ['1', (4, 3)], ['1', (4, 8)], ['2', (10, 8)]]

grpd_prtls = [[n, [p[1]
               for p in prtls if p[0] == n]]
              for n in sorted(set(p[0] for p in prtls))]
grpd_prtls
Out[207]: [['1', [(4, 3), (4, 8)]], ['2', [(1, 1), (10, 8)]]]

grpd_prtls按门户号排序sorted(set(p[0] for p in prtls))

从我的 grpd_prtls 计算 'Manhatten Distance',假设每个数字只有 2 个门户

[[p[0], sum(abs(a-b)
            for a, b in zip(*p[1]))]
 for p in grpd_prtls] 
Out[214]: [['1', 5], ['2', 16]]