Python无法比较字符串

2024-04-25 19:18:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我在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),确保它没有找到当前门户本身。最后计算起点与当前入口、双门与目标之间的距离。你知道吗

但是maze[i][j] == maze[portal[0]][portal[1]]似乎不起作用,因为我的程序总是告诉我另一个入口位于i=9,j=19,不管是哪个入口。奇怪的是,如果我在自己的python上测试字符串的相等性,就会发现它总是错误的。我做错什么了?我现在花了3个多小时寻找错误,但似乎找不到。也许真的很蠢? 另外,请忍受我糟糕的代码。我刚开始学python。你知道吗


Tags: andinforlen门户range数字abs
2条回答

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

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

为了提高可读性,我在atempt中的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\U prtls计算“Manhatten距离”,假设每个数字只有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]]

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个项目,则可以使用列表[0]、列表[1]等访问它们)。 因此,如果您想访问dict中的某个项目,只需传递密钥。在您的启发式算法中,您似乎希望找到[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应该是一个字符。你知道吗

相关问题 更多 >