【发布时间】:2019-03-02 21:27:53
【问题描述】:
我想从给定方向列表中返回最简单的方向集。所以,如果方向集有"SOUTH"后跟"NORTH",反之亦然,它们应该相互抵消;与"WEST" 相同,后跟"EAST",反之亦然。
例如,如果给定的方向列表是["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"],那么正确的输出应该是返回简化列表['WEST']。我的逻辑是按以下方式进行:
- 列表有 7 个元素。在第一遍中,元素 0 和 1 被删除(
"NORTH", "SOUTH"),3 和 4 也被删除("EAST", "WEST")。所以现在列表是['SOUTH', 'NORTH', 'WEST']。比较移除前后列表的长度;如果它们相同,则中断 - 否则,重复。由于新旧长度分别为 7 和 3,因此重复该过程。 - 列表现在有 3 个元素。在第二遍中,元素 0 和 1 被取消 (
'SOUTH', 'NORTH')。所以现在列表变成了['WEST']。再次,比较移除前后的列表长度;如果它们相同,则中断 - 否则,重复。由于新旧长度分别为 3 和 1,因此重复该过程。 - 在第三遍中,没有元素对被删除。比较移除前后列表的长度;如果它们相同,则中断 - 否则,重复。由于新旧长度分别为 1 和 1,因此它会中断该过程并将列表返回为
['WEST']。
我的实现代码如下:
arr = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
while True:
for i in range(len(arr)):
try:
len_old = len(arr)
if ( ((arr[i]=='NORTH' and arr[i+1]=='SOUTH') or (arr[i]=='SOUTH' and arr[i+1]=='NORTH')) or
((arr[i]=='EAST' and arr[i+1]=='WEST') or (arr[i]=='WEST' and arr[i+1]=='EAST')) ):
arr.remove(arr[i])
arr.remove(arr[i])
len_new = len(arr)
if len_new==len_old:
break
except:
pass
arr
但问题是,它永远不会终止。当我手动强制代码停止并检查列表的值以及列表的新旧长度时,它会返回正确的值:
print(arr)
print(len_new)
print(len_old)
>>>
['WEST']
1
1
那么,代码有什么问题?为什么即使达到了中断条件,它也不会中断,我该如何解决?
【问题讨论】:
-
break在 Python 中只能打破最里面的循环。在您的情况下,它是for。while永远不会被破坏。要么设置一个会破坏while的标志,要么将所有内容包装在一个函数中并使用return作为多级中断。 -
您有 2 个循环:
while和for。break只跳出for循环。 -
另外,请注意您的算法无法处理
["WEST", "SOUTH", "EAST", "NORTH"]。 -
那我该如何解决呢?我再次将 if-break 条件放在 for 循环的末尾;它在第一遍返回
['SOUTH', 'NORTH', 'WEST']后中断,这是不正确的。 -
@Amadan 这就是要求 - 像
["WEST", "SOUTH", "EAST", "NORTH"]和["NORTH", "WEST", "SOUTH", "EAST"]这样的列表已经是我正在解决的问题的简化形式,因为在我的问题中,只有成对的方向应该相互取消,而不是四个方向。但是,是的,一般来说你是对的 - 这些四倍,甚至八倍等方向也应该相互取消 - 但那是另一天。
标签: python list while-loop break terminate