【问题标题】:if block in python not executed with True statement如果python中的块没有用True语句执行
【发布时间】:2017-06-13 09:52:33
【问题描述】:

我刚开始用小脚本学习 python。我遇到了一个测验,以确定如果第一行与第一列相同,则列表是对称的, 第二行与第二列相同,依此类推。

def symmetric(block):
    n = len(block)
    i = 0
    for i in range(n-1):
        j = 0
        for j in range(n-1):
            if (block[i][j] != block[j][i]):
                return False
            j +=1
        i +=1
    return True

所以结果

print symmetric([["cat", "dog", "fish"],
                ["dog", "dog", "dog"],
                ["fish","fish","cat"]])

应该是假的。

然而,这段代码总是返回 True,在调试器中我可以看到 block[i][j] != block[j][i] 返回 True 但 if 块没有执行。比较有什么问题还是 if 块没有正确组合?

【问题讨论】:

  • 请修正缩进。严重缩进的 Python 代码是无稽之谈。
  • 第三行i = 0没有意义!第五行也一样。

标签: python string if-statement


【解决方案1】:

它失败的主要原因是你应该写range(n)而不是range(n-1)(上限是独占)。喜欢:

def symmetric(block):
    n = len(block)
    for i in range(n):
        for j in range(n):
            if block[i][j] != block[j][i]:
                return False
    return True

不过,这个函数有几个奇怪的地方:

  • 您初始化i = 0j = 0。这不是必需的:在 Python 中,for 循环将为您声明变量;
  • 您对ij 执行递增/递减,这又是不必要的。 for 循环枚举迭代器/生成器并将每个值分配给 ij
  • 通常不会为if 语句写括号。

此外,您实际上可以使用带有all(..) 内置函数的两行代码使这段代码更优雅:

def symmetric(block):
    n = len(block)
    return all(block[i][j] == block[j][i] for i in range(n) for j in range(n))

这是一种更声明性和更显式的代码编写风格。因为这里的代码几乎是不言自明的:“返回range(n)中的ij中的所有block[i][j] == block[j][i]range(n)中的j

最后就像@Błotosmętek 在他们的评论中所说,如果您已经检查过block[0][2] == block[2][0],则不必检查block[2][0] == block[0][2]。所以你可以通过编写来提高性能(大约一半):

def symmetric(block):
    n = len(block)
    return all(block[i][j] == block[j][i] for i in range(n) for j in range(i))

【讨论】:

  • 非常感谢!但是我不明白上限是否在 range() 中是独占的,为什么没有抛出错误?内置函数非常优雅。不敢相信代码可以这么简洁......
  • @missmissyou:如果你写range(3),它将发出012。所以3不包括在输出中。由于“矩阵”的长度为 3,因此您将覆盖所有有效索引 0、1 和 2。这就是为什么边界是排他性的。
  • 一个小的改进——通过一个三角形矩阵就足够了,因为对角线上的元素总是等于它们自己:return all(block[i][j] == block[j][i] for i in range(1,n) for j in range(i-1))
  • @Błotosmętek:不应该是range(i)吗?请注意,上限是专有的:)
  • @WillemVanOnsem 我很清楚这一点,是的,你说得对,我一开始想写得有点不同,改变了想法,没有更正这一点。
【解决方案2】:

您应该使用range(n) 而不是range(n-1)range 生成的序列不包括上限。

【讨论】:

  • 感谢您的回答。更改为 range(n-1) 可以解决问题,但是在调试器中我可以看到 block[0][2] 和 block[2][0] 已到达...
【解决方案3】:
def symmetric(block):
    n = len(block)
    for i in range(n):
        for j in range(n):
            print i, j
            if (block[i][j] != block[j][i]):
                return False
    return True

print symmetric([["cat", "dog", "fish"],
                ["dog", "dog", "dog"],
                ["fish","fish","cat"]])

在python中你不必声明或增加用于循环的变量,python“for-loop”足够智能,可以为我们做这件事。

你还得研究一下python中range函数是如何工作的,range()可以通过三种方式调用,

range(N-number of times to loop): range 将返回一个从 0 到 N-1 的 N 个整数的列表。

range(S-start position, N-end position):在这种情况下 range 将返回一个从 S 到 N-1 的 (N-S) 个整数列表。

range(S-start position, N-end position, K-steps):这里range会返回一个(N-S)/K个整数列表,从S到N-1,间隔为K。

当您说range(n-1) 时,您的循环仅在索引 0,1 上迭代,跳过索引 2,难怪您每次都得到 True。

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 2023-04-04
    • 2013-11-17
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    相关资源
    最近更新 更多