Python : 튜플의 값 변경
나는 파이썬을 처음 사용 하므로이 질문은 약간 기본적 일 수 있습니다. values
다음을 포함 하는 튜플 이 있습니다.
('275', '54000', '0.0', '5000.0', '0.0')
275
이 튜플 의 첫 번째 값 (즉, ) 을 변경하고 싶지만 튜플이 변경 불가능하므로 values[0] = 200
작동하지 않는다는 것을 이해합니다 . 이것을 어떻게 할 수 있습니까?
먼저 물어볼 필요가 있습니다. 왜 이것을하고 싶습니까?
그러나 다음을 통해 가능합니다.
t = ('275', '54000', '0.0', '5000.0', '0.0')
lst = list(t)
lst[0] = '300'
t = tuple(lst)
하지만 변경해야 할 경우에는 그대로 유지하는 것이 좋습니다. list
문제에 따라 슬라이싱은 정말 깔끔한 솔루션이 될 수 있습니다.
>>> 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)
이를 통해 여러 요소를 추가하거나 몇 가지 요소를 대체 할 수 있습니다 (특히 "이웃"인 경우). 위의 경우 목록으로 캐스팅하는 것이 더 적절하고 읽기 쉽습니다 (슬라이싱 표기법이 훨씬 더 짧더라도).
글쎄, 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
따라서 튜플이 짧으면 슬라이스하고 연결하십시오. 길이가 길면 목록 변환을 수행하십시오!
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')
Not that this is superior, but if anyone is curious it can be done on one line with:
tuple = tuple([200 if i == 0 else _ for i, _ in enumerate(tuple)])
I believe this technically answers the question, but don't do this at home. At the moment, all answers involve creating a new tuple, but you can use ctypes
to modify a tuple in-memory. Relying on various implementation details of CPython on a 64-bit system, one way to do this is as follows:
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
It is a straightfoward one-liner using idoimatic Python:
values = ('275', '54000', '0.0', '5000.0', '0.0')
values = ('300', *values[1:])
EDIT: This doesn't work on tuples with duplicate entries yet!!
Based on Pooya's idea:
If you are planning on doing this often (which you shouldn't since tuples are inmutable for a 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 Jon's idea:
def modTupByIndex(tup, index, ins):
lst = list(tup)
lst[index] = ins
return tuple(lst)
print modTupByIndex((1,2,3),1,"a")
based on Jon's 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 of your old values occurrences
Frist, ask yourself why you want to mutate your tuple
. There is a reason why strings and tuple are immutable in Ptyhon, if you want to mutate your tuple
then it should probably be a list
instead.
Second, if you still wish to mutate your tuple then you can convert your tuple
to a list
then convert it back, and reassign the new tuple to the same variable. This is great if you are only going to mutate your tuple once. Otherwise, I personally think that is counterintuitive. Because It is essentially creating a new tuple and every time if you wish to mutate the tuple you would have to perform the conversion. Also If you read the code it would be confusing to think why not just create a list
? But it is nice because it doesn't require any library.
I suggest using mutabletuple(typename, field_names, default=MtNoDefault)
from mutabletuple 0.2. I personally think this way is a more intuitive and readable. The personal reading the code would know that writer intends to mutate this tuple in the future. The downside compares to the list
conversion method above is that this requires you to import additional py file.
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: Don't try to mutate tuple
. if you do and it is a one-time operation convert tuple
to list, mutate it, turn list
into a new tuple
, and reassign back to the variable holding old tuple
. If desires tuple
and somehow want to avoid list
and want to mutate more than once then create mutabletuple
.
You can't. If you want to change it, you need to use a list instead of a tuple.
Note that you could instead make a new tuple that has the new value as its first element.
I've found the best way to edit tuples is to recreate the tuple using the previous version as the base.
Here's an example I used for making a lighter version of a colour (I had it open already at the time):
colour = tuple([c+50 for c in colour])
What it does, is it goes through the tuple 'colour' and reads each item, does something to it, and finally adds it to the new tuple.
So what you'd want 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])
That specific one doesn't work, but the concept is what you need.
tuple = (0, 1, 2)
tuple = iterate through tuple, alter each item as needed
that's the concept.
I´m late to the game but I think the simplest, resource-friendliest and fastest way (depending on the situation), is to overwrite the tuple itself. Since this would remove the need for the list & variable creation and is archived in one line.
new = 24
t = (1, 2, 3)
t = (t[0],t[1],new)
>>> (1, 2, 24)
But: This is only handy for rather small tuples and also limits you to a fixed tuple value, nevertheless, this is the case for tuples most of the time anyway.
So in this particular case it would 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')
i did this:
list = [1,2,3,4,5]
tuple = (list)
and to change, just do
list[0]=6
and u can change a tuple :D
here is it 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]
You can change the value of tuple using copy 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]
참고URL : https://stackoverflow.com/questions/11458239/python-changing-value-in-a-tuple
'Programing' 카테고리의 다른 글
SELF JOIN이란 무엇이며 언제 사용합니까? (0) | 2020.08.23 |
---|---|
Ipython 노트북 / Jupyter에서 Pandas는 내가 플롯하려는 그래프를 표시하지 않습니다. (0) | 2020.08.23 |
문자열이 배열입니까? (0) | 2020.08.23 |
장치에서 sqlite 데이터베이스의 위치 (0) | 2020.08.23 |
모바일 장치에서 jQuery UI 슬라이더 터치 및 드래그 / 드롭 지원 (0) | 2020.08.23 |