如何改变元组中的值?
- 2025-02-18 09:24:00
- admin 原创
- 29
问题描述:
我有一个名为的元组values
,其中包含以下内容:
('275', '54000', '0.0', '5000.0', '0.0')
我想更改275
此元组中的第一个值(即),但我知道元组是不可变的,因此values[0] = 200
行不通。我该如何实现?
解决方案 1:
可以通过以下方式实现:
t = ('275', '54000', '0.0', '5000.0', '0.0')
lst = list(t)
lst[0] = '300'
t = tuple(lst)
但如果你需要改变一些东西,你最好把它保留为list
解决方案 2:
根据您的问题,切片可能是一个非常好的解决方案:
>>> 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)
这允许您添加多个元素或替换一些元素(特别是如果它们是“邻居”。在上述情况下,转换为列表可能更合适且更易读(即使切片符号要短得多)。
解决方案 3:
嗯,正如 Trufa 已经展示的那样,替换给定索引处的元组元素基本上有两种方法。要么将元组转换为列表,替换元素并转换回来,要么通过连接构造一个新的元组。
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
此外,连接方法的性能取决于我们替换元素的索引。对于列表方法,索引是无关紧要的。
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
因此:如果元组较短,则进行切片和连接。如果元组较长,则进行列表转换!
解决方案 4:
只需一行代码即可:
values = ('275', '54000', '0.0', '5000.0', '0.0')
values = ('300', *values[1:])
解决方案 5:
我相信这在技术上回答了这个问题,但不要在家里这样做。目前,所有答案都涉及创建一个新的元组,但您可以使用它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
解决方案 6:
正如 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')
解决方案 7:
这并不是说这种方法更好,但是如果有人好奇的话,可以一行完成:
tuple = tuple([200 if i == 0 else _ for i, _ in enumerate(tuple)])
解决方案 8:
您不能修改元组中的项目,但可以修改元组中可变对象的属性(例如,如果这些对象是列表或实际的类对象)
例如
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')
解决方案 9:
编辑:这对具有重复条目的元组还不起作用!!
根据Pooya 的想法:
如果您打算经常这样做(您不应该这样做,因为元组是不可变的),您应该做这样的事情:
def modTupByIndex(tup, index, ins):
return tuple(tup[0:index]) + (ins,) + tuple(tup[index+1:])
print modTupByIndex((1,2,3),2,"a")
或者基于Jon的想法:
def modTupByIndex(tup, index, ins):
lst = list(tup)
lst[index] = ins
return tuple(lst)
print modTupByIndex((1,2,3),1,"a")
解决方案 10:
基于Jon的想法和亲爱的Trufa
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")
它会改变你所有的旧价值观
解决方案 11:
不可以。如果要更改它,则需要使用列表而不是元组。
请注意,您可以创建一个新的元组,以新值作为其第一个元素。
解决方案 12:
首先,问问自己为什么要改变你的tuple
。在 Ptyhon 中字符串和元组是不可变的,这是有原因的,如果你想改变你的,tuple
那么它可能应该是list
。
其次,如果您仍希望改变元组,则可以将 转换tuple
为 ,list
然后再转换回来,并将新元组重新分配给同一变量。如果您只打算改变元组一次,那么这很好。否则,我个人认为这是违反直觉的。因为它本质上是创建一个新元组,每次如果您想改变元组,您都必须执行转换。此外,如果您阅读代码,您会困惑地想为什么不直接创建一个list
?但这很好,因为它不需要任何库。
我建议mutabletuple(typename, field_names, default=MtNoDefault)
从mutabletuple 0.2开始使用。个人认为这种方式更直观,可读性更强。读代码的人知道作者以后会改变这个 tuple。缺点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
TL;DR:不要尝试改变tuple
。如果这样做,并且这是一次性操作,请转换tuple
为列表,对其进行变异,变成list
新的tuple
,然后重新分配回保存旧 的变量tuple
。如果愿意tuple
并以某种方式想要避免list
并且想要多次变异,则创建mutabletuple
。
解决方案 13:
我发现编辑元组的最佳方法是使用以前的版本作为基础重新创建元组。
下面是我用来制作较浅颜色版本的示例(当时我已经打开了它):
colour = tuple([c+50 for c in colour])
它的作用是遍历元组“颜色”并读取每个项目,对其进行处理,最后将其添加到新元组中。
因此,你想要的是类似这样的内容:
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 = 遍历元组,根据需要修改每个项目
这就是概念。
解决方案 14:
我迟到了,但我认为最简单、最节省资源和最快的方法(视情况而定)是覆盖元组本身。因为这将消除创建列表和变量的需要,并且可以在一行中归档。
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')
解决方案 15:
如果你想这样做,你可能不想到处乱扔一堆奇怪的函数,并提醒人们你想改变特定事物中的值却无法做到这一点。此外,我们可以继续假设你效率不高。
t = tuple([new_value if p == old_value else p for p in t])
解决方案 16:
受@fuglede启发:使用NumPy,修改元组实际上非常容易。只需将缓冲区a的值复制到缓冲区b。修改后元组即可使用,但不这样做肯定更安全。(不要在家尝试)
import ctypes
import sys
import numpy as np
def changetuples(v, new, ind):
# tuple value to buffer
buff = (ctypes.c_uint8 * (sys.getsizeof(v[ind]))).from_address(id(v[ind]))
ax = np.frombuffer(buff, dtype=np.uint8)
# new value to buffer
buff2 = (ctypes.c_uint8 * (sys.getsizeof(new))).from_address(id(new))
ax2 = np.frombuffer(buff2, dtype=np.uint8)
# copying each byte from one buffer to another
for i in range(len(ax2)):
try:
ax[i] = ax2[i]
except Exception:
return False
return True
t = ("275", 54000, "0.0", "5000.0", "0.0")
newvar = "200" # the new string needs to be <= the old string
index = 0
print(id(t), t)
changetuples(v=t, new=newvar, ind=index)
print(id(t), t)
index = 1
newvar = 20.1
changetuples(v=t, new=newvar, ind=index)
print(id(t), t)
2424588439760 ('275', 54000, '0.0', '5000.0', '0.0')
2424588439760 ('200', 54000, '0.0', '5000.0', '0.0')
2424588439760 ('200', 20.1, '0.0', '5000.0', '0.0')
解决方案 17:
我这样做了:
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]
解决方案 18:
您可以使用引用复制来更改元组的值
>>> tuple1=[20,30,40]
>>> tuple2=tuple1
>>> tuple2
[20, 30, 40]
>>> tuple2[1]=10
>>> print(tuple2)
[20, 10, 40]
>>> print(tuple1)
[20, 10, 40]
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)