[英]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
)的門戶來找到當前門戶本身。 最終,它計算起點和當前門戶之間的距離,以及其雙門戶和目標之間的距離。
但是好像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計算“曼哈頓距離”,每個數字僅配置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]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.