Python: changing a value in a tuple

I am new to python, so this question may be a bit basic. I have a tuple called values that contains the following:

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

I want to change the first value (ie 275 ) in this tuple, but I understand that the tuples are immutable, so values[0] = 200 will not work. How can I achieve this?

+97
python tuples
Jul 12 '12 at 18:27
source share
15 answers

First you need to ask why you want to do this?

But this is possible through:

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

But if you need to change something, you are probably better off keeping it as a list

+143
Jul 12 '12 at 18:29
source share

Depending on your problem, slicing can be a really neat solution:

 >>> 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) 

This allows you to add multiple elements or replace multiple elements (especially if they are “neighbors.” In the example above, listing in the list is probably more appropriate and readable (although the slice notation is much shorter).

+57
Mar 27 '14 at 0:53
source share

Well, as Trufa has already shown, there are basically two ways to replace a tuple element with a given index. Either convert the tuple to a list, replace the element and convert it back, or build a new tuple by concatenation.

 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:] ...: 

So which method is better, i.e. faster?

It turns out that for short tuples (in Python 3.3), concatenation is faster!

 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 

However, if we look at longer tuples, list conversion is a way:

 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 

For very long tuples, list conversion is much better!

 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 addition, the performance of the concatenation method depends on the index in which we replace the element. For a list method, the index does not matter.

 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 

So: if your tuple is short, cut and join. If it is long, do the list conversion!

+18
Nov 23 '13 at 10:14
source share

As Hunter Macmillen wrote in the comments, tuples are immutable, for this you need to create a new tuple. For example:

 >>> 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') 
+6
Jun 13 '16 at 8:36
source share

Not that it was better, but if anyone is interested, this can be done on one line:

 tuple = tuple([200 if i == 0 else _ for i, _ in enumerate(tuple)]) 
+6
Nov 11 '16 at 19:28
source share

I believe this technically answers the question, but don't do this at home. ctypes now, all answers include creating a new tuple, but you can use ctypes to change the tuple in memory. Based on various details of the implementation of CPython in a 64-bit system, the following can be done:

 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
Aug 15 '17 at 17:33
source share

This is a simple one-line text using Python: idoimatic:

 values = ('275', '54000', '0.0', '5000.0', '0.0') values = ('300', *values[1:]) 
+5
Oct 05 '18 at 3:21
source share

based on Jon Idea and dear 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") 

it changes all your old entry values

+2
Jul 12 '12 at 18:37
source share

EDIT: This does not work with tuples with duplicate entries.

Based on the idea of ​​Pooya :

If you plan to do this often (which you should not do, because tuples are not processable for any reason), you should do something like this:

 def modTupByIndex(tup, index, ins): return tuple(tup[0:index]) + (ins,) + tuple(tup[index+1:]) print modTupByIndex((1,2,3),2,"a") 

Or based on John's idea :

 def modTupByIndex(tup, index, ins): lst = list(tup) lst[index] = ins return tuple(lst) print modTupByIndex((1,2,3),1,"a") 
+2
Jul 12 2018-12-12T00:
source share

Frist, ask yourself why you want to change your tuple . There is a reason that strings and tuples are immutable in Ptyhon , if you want to change your tuple , then this should probably be list .

Secondly, if you still want to change your tuple, you can convert your tuple to list , and then convert it and reassign a new tuple to the same variable. This is great if you are only going to change your tuple once . Otherwise, I personally think that this is illogical. Since it essentially creates a new tuple, and each time you want to change the tuple, you have to do the conversion. Also, if you read the code, it would be weird to think, why not just create a list ? But this is good, because it does not require any library.

I suggest using mutabletuple(typename, field_names, default=MtNoDefault) from mutabletuple 0.2 . I personally believe that this method is more intuitive and readable. . A personal reading of the code will know that the author intends to change this tuple in the future. The disadvantage of comparing with the list method above is that you need to import an additional py file for this.

 from mutabletuple import mutabletuple myTuple = mutabletuple('myTuple', 'vwxy z') p = myTuple('275', '54000', '0.0', '5000.0', '0.0') print(pv) #print 275 pv = '200' #mutate myTuple print(pv) #print 200 

TL; DR : do not try to mutate tuple . if you do, and this is a one-time operation, convert tuple to enumerate, mutate it, turn list into a new tuple and reassign it back to a variable containing the old tuple . If you want tuple and somehow want to avoid list and want to mutate more than once, create mutabletuple .

+2
Aug 15 '17 at 18:54 on
source share

You can not. If you want to change it, you need to use a list instead of a tuple.

Note that instead, you can create a new tuple with a new value as its first element.

0
Jul 12 '12 at 18:29
source share

I found that the best way to edit tuples is to recreate the tuple using the previous version as the base.

Here is an example that I used to create a lighter version of the color (I had it open already at that time):

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

What he does is go through the "color" of the tuple and read each element, do something with it, and finally add it to the new tuple.

So, what would you like would be something like:

 values = ('275', '54000', '0.0', '5000.0', '0.0') values = (tuple(for i in values: if i = 0: i = 200 else i = values[i]) 

This particular one does not work, but the concept is what you need.

 tuple = (0, 1, 2) 

tuple = iteration through a tuple, changing each element as needed

what a concept.

0
Mar 18 '16 at 3:48
source share

I'm late for the game, but I think the easiest, resource-friendly and fastest way (depending on the situation) is to rewrite the tuple itself. As this will eliminate the need for a list & variable creation and archived on one line.

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

But: this is convenient only for relatively small tuples, and also limits you to a fixed value of the tuple, however, in any case, in most cases this is the case.

So in this particular case it will look like this:

 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') 
0
Sep 01 '19 at 12:49
source share

I have done this:

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

and change just do

 list[0]=6 

and u can change the tuple: D

here it is copied exactly from 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] 
-2
Nov 01 '14 at 21:11
source share

You can change the value of a tuple by copying by reference

 >>> tuple1=[20,30,40] >>> tuple2=tuple1 >>> tuple2 [20, 30, 40] >>> tuple2[1]=10 >>> print(tuple2) [20, 10, 40] >>> print(tuple1) [20, 10, 40] 
-3
Oct 02
source share



All Articles