如何检查在"0"和"1"的 2D 列表中没有"1"接触边框



我需要考虑游泳池"legitimate"。对于给定的列表,函数应返回"illegitimate"。但是,我的代码返回"legitimate",即使我没有对数据做任何事情。

这是我尝试过的代码,在尝试修改列表之前,我期望/应该返回"illegitimate"

pool = [[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[1, 1, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0]]
def is_legitimate_pool(pool):
for r in range(len(pool)):
for l in range(len(pool[r])):
if pool[r][0] == 1 or pool[4][l] == 1:
return str("illegitimate")
elif pool[r][0] == 0 or pool[4][l] == 0:
return str("legitimate")
print(is_legitimate_pool(pool))

解决方案

您可以从检查第一个和最后一个子列表中是否有任何元素不为零开始。传递给bool(i)的任何非零整数i的计算结果都将为True,只有零是"假的"(请参阅真值检验)。这使我们能够简单地使用内置的any函数来检查这两个列表。如果返回 True,则至少有一个元素为零。

然后我们只是遍历其他子列表,并检查它们的第一个或最后一个元素是否是假的(即零)。如果至少有一个不是,我们可以立即返回。如果我们到达循环的尽头,这意味着"池是合法的"。

法典

LEGIT = "legitimate"
NOT_LEGIT = "illegitimate"
def is_legitimate_pool(pool: list[list[int]]) -> str:
if any(pool[0]) or any(pool[-1]):
return NOT_LEGIT
for row in pool[1:-1]:
if row[0] or row[-1]:
return NOT_LEGIT
return LEGIT

测试

test_pool1 = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[1, 1, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
]
test_pool2 = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 1, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
]
test_pool3 = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 1, 1, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 0],
]
print(is_legitimate_pool(test_pool1))  # illegitimate
print(is_legitimate_pool(test_pool2))  # illegitimate
print(is_legitimate_pool(test_pool3))  # legitimate
<小时 />

注意事项

当然,假设我们只对0的"池的边界"感兴趣,并且元素只能是01。如果你真的需要显式检查边框元素是否1s,我们必须更严格一点:

def is_legitimate_pool(pool: list[list[int]]) -> str:
if any(element == 1 for element in pool[0] + pool[-1]):
return NOT_LEGIT
for row in pool[1:-1]:
if row[0] == 1 or row[-1] == 1:
return NOT_LEGIT
return LEGIT

>代码中的错误您的原始函数存在许多问题。其中之一是,在检查每个子列表之前,您不得返回。您需要检查它们中的每一个,但是如果您的elif条件成立,则您有一个返回"合法"的语句,只要只有一行满足该条件,就会中断循环。

第二个问题是你的索引都搞砸了。表达式if pool[r][0] == 1 or pool[4][l] == 1等效于说"如果第r行中的第 0 个元素或第4行中的第l个元素等于1"。所以你第二部分只检查第4行。在这两种情况下,您都应该检查行r,但是对于该行中的第0个和第4个元素1,所以像这样:if pool[r][0] == 1 or pool[r][4] == 1.

最后,您没有考虑到第一行和最后一行根本不必须包含任何1这一事实。您必须在某个时候(最好在开始循环之前)检查这一点。

优化

修复这些问题将使函数正常工作,但它仍然是次优的,因为您只能处理5x5列表的列表,因为您将索引4硬编码为表示"最后一个"元素。如果您改用索引-1则无论列表有多长,它都将引用最后一个元素。

为了可读性,您应该尽可能避免"索引杂耍",而是利用列表是可迭代的这一事实,因此可以在for循环中使用,这些循环一个接一个地生成每个元素。这样我们就可以显式地命名和处理pool中的每个子列表/行,使代码对读者/你自己来说更清晰。

str("legitimate")是字符串文字"legitimate"上的无操作。您不需要str功能。

应避免在本地命名空间中隐藏全局名称。这意味着,如果你有一个名为pool的全局变量,则函数中不应该pool局部范围的变量。更改其中一个,以便它们具有不同的名称。

最新更新