Python 元组...不是元组吗?逗号有什么作用?

2022-01-20 00:00:00 python python-3.x tuples

问题描述

我正在查看课程材料中的代码,必须编写一个函数,将值 99 添加到 listtuple.最终代码如下所示:

I was looking at code in my course material and had to write a function which adds the value 99 to either a list or tuple. The final code looks like this:

def f(l):
    print(l)
    l += 99,
    print(l)

f([1,2,3])
f((1,2,3))

这用于显示不同的东西,但我有点挂在 l += 99, 行上.这样做是创建一个包含 99 和 list 以及 tuple 的可迭代对象,支持简单添加"此类对象以创建新实例/添加新元素.

This was used to show something different but I'm getting somewhat hung up on the line l += 99,. What this does, is create an iterable that contains the 99 and list as well as tuple support the simple "addition" of such an object to create a new instance/add a new element.

我真正不明白的是使用语法 element, 究竟创建了什么?如果我执行像 x = 99, 这样的分配,则 type(x) 将是 tuple 但如果我尝试运行 x = tuple(99) 它将失败,因为 99 不可迭代.也有:

What I don't really get is what exactly is created using the syntax element,? If I do an assignment like x = 99, the type(x) will be tuple but if I try run x = tuple(99) it will fail as the 99 is not iterable. So is there:

  • 使用 element,?
  • 语法创建的某种中间可迭代对象
  • 是否定义了一个特殊函数,允许在没有可迭代的情况下调用 tuple 并且以某种方式将 , 映射到该函数?
  • Some kind of intermediate iterable object created using the syntax element,?
  • Is there a special function defined that would allow the calling of tuple without an iterable and somehow , is mapped to that?

万一有人想知道为什么接受的答案是这个答案:我的第二个问题的解释做到了.我应该对我的问题更清楚,但 += 实际上让我感到困惑,这个答案包括关于此的信息.

In case anyone wonders why the accepted answer is the one it is: The explanation for my second question made it. I should've been more clear with my question but that += is what actuallly got me confused and this answer includes information on this.


解决方案

语法 element, 只是创建一个中间"tuple,而不是其他类型的对象(虽然 tuple 当然是可迭代的).

The syntax element, simply creates an "intermediate" tuple, not some other kind of object (though a tuple is of course iterable).

但是,有时您需要使用括号以避免歧义.出于这个原因,你会经常看到这样的:

However, sometimes you need to use parentheses in order to avoid ambiguity. For this reason, you'll often see this:

l += (99,)

...即使括号在语法上不是必需的.我也碰巧认为这更容易阅读.但是括号在您已经发现的其他情况下在语法上是必需的:

...even though the parentheses are not syntactically necessary. I also happen to think that is easier to read. But the parentheses ARE syntactically necessary in other situations, which you have already discovered:

list((99,))
tuple((99,))
set((99,))

您也可以这样做,因为 [] 会生成一个 list:

You can also do these, since [] makes a list:

list([99])
tuple([99])
set([99])

...但是你不能这样做,因为 99, 在这些情况下不是 tuple 对象:

...but you can't do these, since 99, is not a tuple object in these situations:

list(99,)
tuple(99,)
set(99,)

要回答您的第二个问题,不,没有办法使 tuple() 函数接收不可迭代.事实上,这是 element,(element,) 语法的目的——非常类似于 [] for list{} 用于 dictset(因为 listdict, 和 set 函数也都需要可迭代的参数):

To answer your second question, no, there is not a way to make the tuple() function receive a non-iterable. In fact this is the purpose of the element, or (element,) syntax - very similar to [] for list and {} for dict and set (since the list, dict, and set functions all also require iterable arguments):

[99] #list 
(99,) #tuple -  note the comma is required
{99} #set

正如问题评论中所讨论的,令人惊讶的是,您可以使用 tuple 对象递增 (+=) list.请注意,您不能这样做:

As discussed in the question comments, it surprising that you can increment (+=) a list using a tuple object. Note that you cannot do this:

l = [1]  
l + (2,) # error

这是不一致的,所以它可能是不应该被允许的事情.相反,您需要执行以下操作之一:

This is inconsistent, so it is probably something that should not have been allowed. Instead, you would need to do one of these:

l += [2]
l += list((2,))

但是,修复它会给人们带来问题(更不用说消除邪恶的计算机科学教授利用混淆的成熟机会),所以他们没有.

However, fixing it would create problems for people (not to mention remove a ripe opportunity for confusion exploitation by evil computer science professors), so they didn't.

相关文章