Python的if语句出现无效语法!为什么?

7
while x < len(Hand):
    while y < len(Hand):
        if Hand[x][0] == Hand[y][0] and y != x:
                sameRank += 1
        y += 1
    x += 1

它在“if”之前突出显示一个空格,并显示语法错误……毫无意义。

7
可能是缩进问题。你有检查过吗? - Rohit Jain
7
在Python中,使用索引循环遍历某个东西是一种非常糟糕的方法。应该使用“for”循环遍历项目而不是索引。至于您的问题,请发布实际错误,这会使事情变得更容易。 - Gareth Latty
3
我猜测if代码块的缩进应该和while代码块一样。请确认您没有混用tab键和空格键。 - cdhowie
6
sum(1 for x in Hand for y in Hand if x[0] == y[0] and y!=x) - Andy Hayden
2
什么解释器?另外,这可能听起来很愚蠢,但从你的顶行开始:到达行末,删除换行符和所有空格,然后重新输入换行符并重新缩进下一行。对于所有行都重复此操作。 - selllikesybok
显示剩余7条评论
3个回答

7
我这里没有发现任何错误,但是有可能你在if语句下面的代码块缩进太多了。请注意,你程序中其余部分都是使用四个空格缩进的。尝试将缩进减少到只有四个空格,看看是否能运行。
然而,你的代码确实存在逻辑错误。如果你不在每个x开始时重新初始化y,就无法对每个x循环遍历y。
以下是我使用修复逻辑错误后的示例代码:
def example():
    Hand = [[1],[2],[3],[3],[4],[5],[2],[2],[1]]
    x = 0 
    sameRank = 0 

    while x < len(Hand):
        y = 0
        while y < len(Hand):
            if Hand[x][0] == Hand[y][0] and y != x:
                sameRank += 1
            y += 1
        x += 1

if __name__ == "__main__":
    example()

最后,通过更加符合Python风格的编写方式,可以使这段代码变得更易读。请考虑以下方法:

def example():
    Hand = [[1],[2],[3],[3],[4],[5],[2],[2],[1]]
    sameRank = 0 

    for x in Hand:
        for y in Hand:
            if x[0] == y[0] and y != x:
                sameRank += 1

if __name__ == "__main__":
    example()

这段代码迭代了Hand的内容,而不是使用临时整数变量并与索引运算符一起使用。这种方法更好,因为"维护"行少(例如x +=1),更易读,并且对类型不敏感,因为它将适用于包含列表的任何可迭代对象。或者甚至可以按照Hayden的评论改为:
def example():
    Hand = [[1],[2],[3],[3],[4],[5],[2],[2],[1]]
    sameRank = sum(1 for x in Hand for y in Hand if x[0] == y[0] and y!=x)

if __name__ == "__main__":
    example()

这段代码将对sum函数的调用与生成器表达式1 for x in Hand for y in Hand if x[0] == y[0] and y!=x相结合。该表达式返回一个生成器,它为符合条件的列表中的每个项产生1,而sum函数将所有这些1加起来,从而给出你对sameRank想要的值。
参考这篇文章以了解Python习语。
最后,我不确定你使用的是哪个编辑器,但如果你收到对话框而不是直接从解释器的stderr/stdout获取消息和traceback,那么它似乎掩盖了真正的问题。当你试图学习时,有时候编辑器提供的帮助过多是一件非常糟糕的事情。我个人使用Vim,但这可能对初学者来说有点困难。我没有太多IDLE的使用经验(你可能正在使用它),但我听说使用它作为学习工具是一个不错的选择。无论如何,如果你使用IDLE,请习惯于从命令行而不是从IDLE本身运行程序。我个人发现在很多情况下这会给我更好的反馈。最后还有PyDev IDE(基于Eclipse构建),特别适用于其强大的内置可视化调试。如果你不熟悉Eclipse,这可能是一个难度较高的“中级”学习选项。如果你熟悉Eclipse,你将对PyDev非常熟悉。

如果我复制并粘贴您的代码,纠正缩进问题,并提供虚拟数据,则对我而言它可以正常工作。如果这不是解决方案,您需要更新您的问题并附上更多程序信息。 - Ben Burns
Python不在乎一行缩进有多少空格,只要同一级别的所有行都缩进相同即可。 - Ethan Furman

1

你可能在if之前有一个类似空格的字符 - 我曾经在使用TextMate时遇到过这种情况,其中alt+space会插入一个非断行空格Unicode字符而不是常规空格。

你的文件开头是否有类似于# coding: utf-8的东西?如果有,请将其删除,你可能会得到更好的错误消息。

顺便说一下,不使用sum/生成表达式(对于学习Python的人来说可能更加混乱),你的循环可以简化如下:

for x in range(len(Hand)):
    for y in range(len(Hand)):
        if Hand[x][0] == Hand[y][0] and y != x:
                sameRank += 1

更好的方法是遍历可迭代对象,而不是创建两个新的可迭代对象来索引现有的可迭代对象,对吧?我发现我实际上很少需要range/xrange内置函数。只有在使用skip参数时才会极其罕见地需要它们来创建临时索引值。 - Ben Burns

0

有时候,制表符和空格的混合使用会导致 Python 出现问题 - 比如说,如果你的 while 循环是用制表符缩进的,而你的 if 语句则使用空格。虽然 if 语句现在可能已经正确缩进了,但最好还是检查一下代码片段中的所有其他行,确保它们都以相同的方式缩进。

以下是一些编辑器可能会提供的帮助:

  • 当你按下 Tab 键时,插入多个空格而不是制表符
  • 显示空白字符,这样你就可以轻松地看到是四个空格还是一个制表符
  • 搜索并替换制表符字符(如果你的编辑器支持正则表达式搜索),将它们与四个空格交换,或者反过来。

如果你的编辑器没有支持上述任何功能,我建议尝试使用 Programmer's NotepadNotepad2,即使只是为了帮助诊断这些问题。

如果这听起来过于挑剔,那就欢迎进入编程的世界吧!即使是最优秀的人也可能感到沮丧。选择你喜欢的版本(空格或制表符),并坚持使用。在Python中,有许多方法可以使代码更加简洁,如上所述,但习惯处理空格问题也是一个好主意。

1
空格。选择使用空格。每次你用制表符缩进时,上帝就会杀死一只小猫。如果你在缩进Python代码时使用制表符,则会有两只小猫被杀死。请参阅PEP-8。http://www.python.org/dev/peps/pep-0008/#tabs-or-spaces - Ben Burns
我很糟糕,总是在这个问题上犹豫不决(删除多余的空格真的很烦人!),但我开始接受使用空格了(设置制表符长度真的很麻烦,而空格在所有情况下都有效!)。 - Hannele
是的,我也曾对此感到纠结。如果你使用一款让你感觉简单的编辑器,你就不会再回头了。 - Ben Burns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接