如何改变元组中的值?

2025-02-18 09:24:00
admin
原创
32
摘要:问题描述:我有一个名为的元组values,其中包含以下内容:('275', '54000', '0.0', '5000.0', '0.0') 我想更改275此元组中的第一个值(即),但我知道元组是不可变的,因此values[0] = 200行不通。我该如何实现?解决方案 1:可以通过以下方式实现:t = ('...

问题描述:

我有一个名为的元组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]
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1325  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它涵盖了从产品概念产生到产品退市的整个生命周期,通过整合跨部门团队、优化流程等方式,显著提升产品开发的效率和质量,进而为项目的成功奠定坚实基础。深入探究IPD流程的五个阶段与项目成功之间...
IPD流程分为几个阶段   4  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,其中的创新管理与实践更是蕴含着丰富的经验和深刻的智慧,对众多企业具有重要的借鉴意义。IPD流程的核心架构IPD流程旨在打破部门墙,实现跨部门的高效协作,将产品开发视为一个整体的流程。它涵盖了从市场需求分析...
华为IPD是什么   3  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发模式,在众多企业的发展历程中发挥了至关重要的作用。它不仅仅是一套流程,更是一种理念,一种能够全方位提升企业竞争力,推动企业持续发展的有效工具。深入探究IPD研发管理体系如何助力企业持续发展,对于众多渴望在市场中立足并...
IPD管理流程   3  
  IPD(Integrated Product Development)流程管理旨在通过整合产品开发流程、团队和资源,实现产品的快速、高质量交付。在这一过程中,有效降低成本是企业提升竞争力的关键。通过优化IPD流程管理中的各个环节,可以在不牺牲产品质量和性能的前提下,实现成本的显著降低,为企业创造更大的价值。优化产品规划...
IPD流程分为几个阶段   4  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用