简体   繁体   English

TypeError:“元组”对象不支持项目分配

[英]TypeError: 'tuple' object does not support item assignment

I'm trying to write a short program which allows the user to input a list of numbers into an input() function, and then using the add_25 function add 25 to each item in a list. 我正在尝试编写一个简短的程序,允许用户将数字列表输入到input()函数中,然后使用add_25函数将25添加到列表中的每个项目。

I get the following error when the program runs: TypeError: 'tuple' object does not support item assignment 程序运行时出现以下错误: TypeError: 'tuple' object does not support item assignment

I tried dividing the numbers using a comma. 我尝试使用逗号对数字进行除法。 This is the program: 这是程序:

testlist = [2,6,2]

def add_25(mylist):

    for i in range(0, len(mylist)):
        mylist[i] = mylist[i] + 25

    return mylist

print add_25(testlist)

actual_list = input("Please input a series of numbers, divided by a comma:")

print add_25(actual_list)

In Python 2 input() will eval the string and in this case it will create a tuple, and as tuples are immutable you'll get that error. 在Python 2中, input()将评估字符串,在这种情况下,它将创建一个元组,并且由于元组是不可变的,因此您将得到该错误。

>>> eval('1, 2, 3')
(1, 2, 3)

It is safer to use raw_input with a list-comprehension here: 在此处 raw_inputlist-comprehension 一起使用会更安全

inp = raw_input("Please input a series of numbers, divided by a comma:")
actual_list = [int(x) for x in inp.split(',')]

Or if you're not worried about user's input then simply convert the tuple to list by passing it to list() . 或者,如果您不担心用户的输入,则只需将元组传递给list()即可将其转换为list()


Also note that as you're trying to update the list in-place inside of the function it makes no sense to return the list unless you want to assign another variable to the same list object. 还要注意,当您尝试在函数内部就地更新列表时,除非您想将另一个变量分配给同一列表对象,否则返回列表是没有意义的。 Either return a new list or don't return anything. 返回新列表或不返回任何内容。

The function input reads a string and evaluates it as a Python expression . 函数input读取一个字符串并将其评估为Python表达式 Thus, the comma-separated list becomes a tuple of values, these are passed to add_25() , and this function tries to assign to mylist[i] something. 因此,以逗号分隔的列表成为值的元组,这些值传递给add_25() ,并且此函数尝试将某些内容分配给mylist[i]

And tuples are immutable, they do not support item assignment (on purpose). 元组是不可变的,它们不支持项目分配(故意)。

You could use actual_list = list(input(...)) to convert the tuple to a list (which supports item assignment). 您可以使用actual_list = list(input(...))将元组转换为list (支持项目分配)。

But every time someone uses input() , one has to warn him: input() is a security risk. 但是每次有人使用input() ,都必须警告他: input()有安全隐患。 It evaluates the input of the user and thus might execute arbitrary things the user typed. 评估 用户的输入,因此可以执行 用户键入的任意操作。 This means that your program will perform what the user asks it to, with your permissions. 这意味着您的程序将在您的许可下执行用户要求的操作。 This is normally not what is considered a good design. 通常这不是一个好的设计。

If you always will be the only user or if you trust all users of your program completely, then so be it. 如果您始终是唯一的用户,或者如果您完全信任程序的所有用户,那么就这样吧。

Besides all the input() aspects covered in the other answers, I'd like to add this completely different aspect: 除了其他答案涵盖的所有input()方面,我还要添加此完全不同的方面:

Your function add_25() is probably not supposed to change its input. 您的函数add_25()可能不应该更改其输入。 Yours does, or tries to, and fails because tuples do not allow that. 您的执行或尝试执行失败,因为元组不允许这样做。

But you actually do not have to change the input (and you should not, because this is not good style due to its ugly side-effects). 但是实际上您不必更改输入(并且您不应该更改输入,因为由于其丑陋的副作用,这不是很好的样式)。 Instead you could just return a new tuple: 相反,您可以只返回一个新的元组:

def add_25(mytuple):
    return tuple(x + 25 for x in mytuple)

This way, nothing is assigned to a tuple, just a new tuple is created and returned. 这样,什么都不分配给元组,仅创建并返回一个新的元组。

def test_tuples_of_one_look_peculiar(self):
    self.assertEqual( __,(1).__class__)
    self.assertEqual(__, (1,).__class__)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM