为什么python在元组设计中选择逗号而不是括号?

时间:2017-07-04 21:14:41

标签: python syntax tuples language-lawyer language-design

来自python wiki

  

多元素元组

     

在Python中,多元素元组看起来像:

     

1,2,3

     

...

     

但同样,定义元组的是逗号,而不是括号。

哦,真的吗?!

然后原因:

>>> tuple((((((1, 2, 3)))))) # creates a valid tuple
# (1, 2, 3)
>>> tuple(1, 2, 3, ) # But not here
# TypeError: tuple() takes at most 1 argument (3 given)

更严重的是,我不明白为什么没有选择括号中的括号?

因为我认为它会在以下情况下产生矛盾:

>>> 1, # is a valid tuple
# (1,)
>>> tuple([1]) # Or this
# (1,)
>>> tuple(1) # But not this one
# TypeError: 'int' object is not iterable

但是,如果您认为括号总是负责实例化tuple,那么使用多个项目实例化tuple的所有问题都将消失。

e.g。在我想象中的世界:

>>> (1, 2, 3) # stay valid
# (1, 2, 3)
>>> (1) # is newly valid
# (1)
>>> () # stay valid
# ()
>>> 1, 
# TypeError: int() takes exactly 1 argument (2 given) 

我知道这是一个众所周知的功能,如果它重复,我已经很抱歉了。我发现了许多关于元组如何工作的类似主题,但没有详细解释为什么这个特性是这样创建的。

我也知道这个主题可以基于意见而被关闭,但我最感兴趣的是技术原因(如果有的话),或者至少历史原因

谢谢

3 个答案:

答案 0 :(得分:7)

这是grammar的神器。

用逗号分隔的术语是元组,列表和集合的构建块,具体取决于它们是用方括号,花括号还是什么都不包含。

指定语法时的主要挑战是平衡相同字符的多个竞争使用。逗号分隔列表,元组,词组和集合的各个部分。逗号还在函数调用中分隔参数。两种用法都允许使用尾随逗号(并且长度为1的元组是必需的)。同样,括号有多种用途,包括函数调用和算术表达式分组。该句点用作小数点和getattribute运算符。

答案 1 :(得分:2)

tuple(..)使采用多个参数的原因是因为(1)单个元素与可转换为元组的迭代之间可能存在混淆,( 2)多个论点。

假设您使用单个可迭代元素调用元组,那么Python是否应该构造带有一个元素的元组可能会产生混淆:可迭代;或者基于给定的可迭代构造的元组。 Python的设计者选择了后者。正如documentation

中指定的那样
  

<强> tuple(iterable)

这是合理的,因为那时可以写:

tuple(x*x for x in somelist if x%2)

例如,构造一个具有somelist的奇数元素的正方形的元组。

在你的第一个例子中:

tuple((((((1, 2, 3))))))

您构建了一个元组(1, 2, 3)。现在,您将该元组作为唯一参数传递给元组构造函数。由于元组是可迭代的,因此您可以根据您传递的唯一可迭代构造元组。

你的表达:

tuple(1, 2, 3, )

但是引发了错

接下来,你有元组文字 。文字是以逗号分隔的表达式列表。它用给定的元素构造一个元组。如果您在没有附加括号的情况下调用方法,则在(1)元组文字之间存在混淆; (2)传递给方法的多个参数。

还有其他这样的&#34;语法&#34; Python中的方面。例如,如果将生成器传递给具有多个参数的函数,则生成器也需要用括号括起来。

答案 2 :(得分:2)

通常,parens除了分组之外不提供任何其他功能,但是当它们出现在可调用之后时,它们具有与仅仅分组表达式不同的内涵;与Haskell不同,Python要求那些parens进行调用。

在下面的示例中,外部的parens绑定到函数调用(语言构造),而嵌套的parens将内部表达式(函数arguments(s))组合为元组:

>>> tuple((1, 2, 3))
(1, 2, 3)

基本上,元组是由逗号创建的。