如何更改元组中的值?

我有一个名为 values的元组,它包含以下内容:

('275', '54000', '0.0', '5000.0', '0.0')

我想更改这个元组中的第一个值(即 275) ,但是我知道元组是不可变的,所以 values[0] = 200不能工作。我怎么才能做到呢?

319235 次浏览

可以通过以下途径实现:

t = ('275', '54000', '0.0', '5000.0', '0.0')
lst = list(t)
lst[0] = '300'
t = tuple(lst)

但是如果你需要改变一些东西,你可能最好保持它作为一个 list

如果你想改变它,你需要使用一个列表而不是一个元组。

注意,您可以创建一个新的元组,它的第一个元素是新值。

基于 乔恩的理念和亲爱的 特鲁法

def modifyTuple(tup, oldval, newval):
lst=list(tup)
for i in range(tup.count(oldval)):
index = lst.index(oldval)
lst[index]=newval


return tuple(lst)


print modTupByIndex((1, 1, 3), 1, "a")

它改变了你所有的旧价值观

编辑: 对于具有重复条目的元组,这还不能工作! !

基于 普亚的主意:

如果您计划经常这样做(不应该这样做,因为元组是不可变的) ,那么您应该这样做:

def modTupByIndex(tup, index, ins):
return tuple(tup[0:index]) + (ins,) + tuple(tup[index+1:])


print modTupByIndex((1,2,3),2,"a")

或基于 乔恩的主意:

def modTupByIndex(tup, index, ins):
lst = list(tup)
lst[index] = ins
return tuple(lst)


print modTupByIndex((1,2,3),1,"a")

好的,正如 Trufa 已经展示的,基本上有两种方法可以替换给定索引处的 tuple 元素。要么将元组转换为列表,替换元素并转换回来,要么通过连接构造一个新的元组。

In [1]: def replace_at_index1(tup, ix, val):
...:     lst = list(tup)
...:     lst[ix] = val
...:     return tuple(lst)
...:


In [2]: def replace_at_index2(tup, ix, val):
...:     return tup[:ix] + (val,) + tup[ix+1:]
...:

那么哪种方法更好,就是更快?

事实证明,对于短元组(在 Python 3.3上) ,连接实际上更快!

In [3]: d = tuple(range(10))


In [4]: %timeit replace_at_index1(d, 5, 99)
1000000 loops, best of 3: 872 ns per loop


In [5]: %timeit replace_at_index2(d, 5, 99)
1000000 loops, best of 3: 642 ns per loop

然而,如果我们看看更长的元组,列表转换是可行的方法:

In [6]: k = tuple(range(1000))


In [7]: %timeit replace_at_index1(k, 500, 99)
100000 loops, best of 3: 9.08 µs per loop


In [8]: %timeit replace_at_index2(k, 500, 99)
100000 loops, best of 3: 10.1 µs per loop

对于非常长的元组,列表转换要好得多!

In [9]: m = tuple(range(1000000))


In [10]: %timeit replace_at_index1(m, 500000, 99)
10 loops, best of 3: 26.6 ms per loop


In [11]: %timeit replace_at_index2(m, 500000, 99)
10 loops, best of 3: 35.9 ms per loop

此外,连接方法的性能取决于替换元素的索引。对于 list 方法,索引是不相关的。

In [12]: %timeit replace_at_index1(m, 900000, 99)
10 loops, best of 3: 26.6 ms per loop


In [13]: %timeit replace_at_index2(m, 900000, 99)
10 loops, best of 3: 49.2 ms per loop

因此: 如果你的元组很短,切片并连接。 如果它很长,就执行列表转换

根据您的问题切片可以是一个非常简洁的解决方案:

>>> b = (1, 2, 3, 4, 5)
>>> b[:2] + (8,9) + b[3:]
(1, 2, 8, 9, 4, 5)
>>> b[:2] + (8,) + b[3:]
(1, 2, 8, 4, 5)

这允许您添加多个元素或替换一些元素(特别是如果它们是“邻居”的话)。在上面的例子中,对列表进行强制转换可能更加合适和可读(尽管切片符号要短得多)。

我是这么做的:

list = [1,2,3,4,5]
tuple = (list)

想要改变,就去做

list[0]=6

你可以改变元组 D

这里是它完全从 IDLE 复制

>>> list=[1,2,3,4,5,6,7,8,9]


>>> tuple=(list)


>>> print(tuple)


[1, 2, 3, 4, 5, 6, 7, 8, 9]


>>> list[0]=6


>>> print(tuple)


[6, 2, 3, 4, 5, 6, 7, 8, 9]

我发现编辑元组的最佳方法是使用以前的版本作为基础重新创建元组。

下面是我用来做一个颜色较浅的版本的例子(当时我已经打开了) :

colour = tuple([c+50 for c in colour])

它所做的,就是通过元组“ color”并读取每个条目,对其进行处理,最后将其添加到新的元组中。

所以你想要的是这样的:

values = ('275', '54000', '0.0', '5000.0', '0.0')


values  = (tuple(for i in values: if i = 0: i = 200 else i = values[i])

具体的那个不起作用,但这个概念是你需要的。

tuple = (0, 1, 2)

Tuple = 遍历 tuple,根据需要修改每个条目

就是这个概念。

正如 Hunter McMillen 提到的,元组是不可变的,您需要创建一个新的元组来实现这一点。例如:

>>> tpl = ('275', '54000', '0.0', '5000.0', '0.0')
>>> change_value = 200
>>> tpl = (change_value,) + tpl[1:]
>>> tpl
(200, '54000', '0.0', '5000.0', '0.0')

并不是说这种方法更优越,但如果有人感到好奇的话,可以用下面这句话来完成:

tuple = tuple([200 if i == 0 else _ for i, _ in enumerate(tuple)])

我相信从技术上来说,这回答了问题,但不要在家里这样做。目前,所有的答案都涉及到创建一个新的元组,但是您可以使用 ctypes来修改内存中的元组。依赖于64位系统上 CPython 的各种实现细节,实现方法如下:

def modify_tuple(t, idx, new_value):
# `id` happens to give the memory address in CPython; you may
# want to use `ctypes.addressof` instead.
element_ptr = (ctypes.c_longlong).from_address(id(t) + (3 + idx)*8)
element_ptr.value = id(new_value)
# Manually increment the reference count to `new_value` to pretend that
# this is not a terrible idea.
ref_count = (ctypes.c_longlong).from_address(id(new_value))
ref_count.value += 1


t = (10, 20, 30)
modify_tuple(t, 1, 50)   # t is now (10, 50, 30)
modify_tuple(t, -1, 50)  # Will probably crash your Python runtime

首先,问问你自己为什么你想要变异你的 tuple字符串和元组在 Ptyhon 是不可变的,这是有原因的 ,如果你想突变你的 tuple,那么它可能应该是一个 list代替。

其次,如果你仍然希望突变你的元组,然后你可以转换你的 tuple到一个 list然后转换回来,并重新分配新的元组到同一个变量。这是伟大的 如果您只打算对元组进行一次变异。否则,我个人认为这是违反直觉的。因为它实际上是在创建一个新的元组,每次如果您希望对元组进行变异,就必须执行转换。另外,如果你阅读代码,它会令人困惑,以为为什么不只是创建一个 list?但是它很好,因为它不需要任何库。

我建议使用 Mutabletuple 0.2中的 mutabletuple(typename, field_names, default=MtNoDefault)。我个人认为这种方式是一个 更直观可读。的个人阅读的代码会知道,作者打算在未来突变这个元组。与上面的 list转换方法相比,缺点是需要导入额外的 py 文件。

from mutabletuple import mutabletuple


myTuple = mutabletuple('myTuple', 'v w x y z')
p = myTuple('275', '54000', '0.0', '5000.0', '0.0')
print(p.v) #print 275
p.v = '200' #mutate myTuple
print(p.v) #print 200

不要试图突变 tuple。如果你这样做,它是一个一次性的操作转换 tuple列表,变异它,把 list到一个新的 tuple,并重新分配回变量持有旧的 tuple。如果想要 tuple并且想要避免 list并且想要变异不止一次,那么创建 mutabletuple

可以通过引用复制来更改元组的值

>>> tuple1=[20,30,40]


>>> tuple2=tuple1


>>> tuple2
[20, 30, 40]


>>> tuple2[1]=10


>>> print(tuple2)
[20, 10, 40]


>>> print(tuple1)
[20, 10, 40]

一句话就可以解决问题:

values = ('275', '54000', '0.0', '5000.0', '0.0')
values = ('300', *values[1:])

我迟到了,但我认为 最简单的,资源友好和最快的方式 (视乎情况而定), 就是覆盖元组本身。因为这将消除创建列表和变量的需要,并将其存档在一行中。

new = 24
t = (1, 2, 3)
t = (t[0],t[1],new)


>>> (1, 2, 24)

但是: 这只适用于相当小的元组,并且还将您限制为固定的元组值,尽管如此,大多数时候元组都是这种情况。

所以在这个特殊的情况下,它看起来是这样的:

new = '200'
t = ('275', '54000', '0.0', '5000.0', '0.0')
t = (new, t[1], t[2], t[3], t[4])


>>> ('200', '54000', '0.0', '5000.0', '0.0')

您不能修改元组中的项,但是您可以修改元组中可变对象的属性(例如,如果这些对象是列表或实际的类对象)

比如说

my_list = [1,2]
tuple_of_lists = (my_list,'hello')
print(tuple_of_lists) # ([1, 2], 'hello')
my_list[0] = 0
print(tuple_of_lists) # ([0, 2], 'hello')