为什么Python字典中008和009无效?

13

为什么我不能把008或009作为Python字典的键,但是001-007可以呢?

some_dict = {
    001: "spam",
    002: "eggs",
    003: "foo",
    004: "bar",
    008: "anything", # Throws a SyntaxError
    009: "nothing"   # Throws a SyntaxError
    }

更新:问题已解决。我不知道以零开始的文字会被视为八进制。这似乎非常奇怪。为什么是零呢?


2
为什么选择Python?历史先例(C语言这样做了)。我不知道为什么要用C语言来实现,因为我同意这是相当愚蠢的。 - Jacob
2
是的,我们被卡住了。如果你必须要有零,那就把它们变成字符串。字典会很好用。 - Jay Atkinson
八进制字面量曾用“o”表示(即o73)。我不知道为什么在C类型语言中将其更改为零(0)。十六进制数(基数16)通常用x(或0x)前缀或'h'后缀(0x2AE,2AEh)表示。一些语言使用前缀“b”来表示二进制数字。 - Robert Cartaino
13
在JavaScript中,使用前导零表示八进制数是很糟糕的,但更糟糕的是,如果一个数字有任何非八进制数字,JavaScript会自动忽略它应该是八进制的事实。因此,在JavaScript中,077表示63的十进制,而078表示78的十进制。这是两者都糟糕的最坏情况。 - Michael Burr
2
罗伯特:你在问为什么将它改成了零,这几乎是40年前的事情。真正的问题是为什么新的编程语言还在继续这样做? - jmucchiello
显示剩余3条评论
5个回答

28

在Python以及其他一些语言中,如果你使用0��为数字的开头,那么这个数字会被解释为八进制(基数8),其中只有0-7是有效数字。你需要将你的代码更改为以下内容:

some_dict = { 
    1: "spam",
    2: "eggs",
    3: "foo",
    4: "bar",
    8: "anything",
    9: "nothing" }

或者如果前导零非常重要,可以使用字符串作为键(key)。


4
我非常非常希望K&R(我认为是他们)没有提出八进制的那种惯例...... - Michael Burr
@Michael - 看起来K&R可能选择了'0',但八进制的前缀形式似乎早于它们。我追溯到最初的BCPL定义。他们可能选择'0'作为词法分析器的一种美观性。 - D.Shawley
我并不太在意它是C语言的惯例,让我困扰的是其他类C语言(不包括那些被设计为直接兼容的语言)也抄袭了这个惯例。我之前并没有意识到Python中存在这个惯例,感觉很糟糕。 - David Thornley

10

Python将008和009视为八进制数,因此...无效。

只能使用007及以下数字,下一个数字将是010(8),然后是011(9)。在Python解释器中尝试一下,你就会明白我的意思。


8
在Python(以及许多其他语言)中,以前导“0”开头的数字表示八进制数(基数为8)。使用这种前导零符号称为八进制字面量。八进制数为0、1、2、3、4、5、6、7、10、11等。因此,08(在八进制中)是无效的。
如果您删除前导零,则代码将正常运行:
some_dict = 
{ 
    1: "spam",
    2: "eggs",
    3: "foo",
    4: "bar",
    8: "anything",
    9: "nothing" 
}

7

@DoxaLogos是正确的。它们不是无效的键 - 它们是无效的文字。如果您尝试在任何其他上下文中使用它们,您将收到相同的错误。


2
这是因为当您以 0 开头的数字时,它被解释为八进制数。由于 008009 不是八进制数,所以会失败。
在八进制数前面加上 0 使得您不必写成 (127)₈。来自维基百科页面的信息: "有时候,八进制数可以通过在值前加上0来表示(例如在Python 2.x或JavaScript 1.x中 - 虽然现在在两者中都已弃用)"

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