-1

I want to subtract 1 from every digit in a tuple using for loop in Python.

I don't understand why my code is returning the original tuple instead of the desired one. Here is the code:

tuple = (3, 2)
for i in tuple:
  i -= 1
print(tuple)

Any idea ?

Kyrol
  • 3,475
  • 7
  • 34
  • 46
Tony Stark
  • 23
  • 6
  • I think it would be helpful for you to try explaining your thinking so that it easier for others to point out where this diverges from how code works. Solution to the problem is simple: `t = (3, 2); t = tuple(x - 1 for x in t)` – norok2 Apr 08 '21 at 12:55
  • 1
    Besides the fact that a tuple is immutable you didn't attempt to update the tuple. You took each element of the tuple and decremented them without any further action. – AcK Apr 08 '21 at 13:24

6 Answers6

2

Tuples are immutable objects, that is, you cannot change the elements of the tuple once it is created, if you do want to change them it would be better to use a list.

a = [3, 2]
for i in a:
    i -= 1
print(a)

Which gives an output:

[3, 2]

Why didn't it work, even though lists are mutable? And also, why doesn't your original code produce some kind of error, if tuples are really immutable? Well, this becomes more obvious if you write your for each style loop as a simple for:

for index in range(len(a)):
    i = a[index]
    i -= 1
print(a)

This code is just a more verbose version of your original example, but now the problem is clear - the code never actually changes the elements of the original list. Instead, each iteration of the for loop creates a new variable, i, which takes its value from the correspondinglist element. i -= 1 changes i, not a[index].

Incidentally, that is why there is no error in your original code, even though tuples are supposed to be immutable - the code simply doesn't try to mutate the original tuple at all.

A working example with a list would be something like:

a = [3, 2]
for index in range(len(a)):
    a[index] -= 1

print(a)

which can be made more concise in the end by writing:

a = [3, 2]
a = [i - 1 for i in a]
print(a)

As an aside, if you really must take tuples as input and produce tuples as output, you can convert between tuples and lists using the list and tuple functions. This is also why you shouldn't use tuple as your variable name! Doing so will mean that you can't use that tuple function in the same scope as your tuple variable, making things very difficult and potentially confusing for you.

L.Grozinger
  • 2,280
  • 1
  • 11
  • 22
1

tuple is immutable

my_tuple = (1,2,3)
my_tuple [0] = 3
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Beny Gj
  • 607
  • 4
  • 16
1
  1. I think tuple is a bad variable name for a tuple because it shadows the tuple of Python

  2. Issue is the values assigned to i are integers and integers themselves are not mutable. So even if i changes, the value in tuple does not. In other words, even though i points to the same object as the integer in tuple, when you do in place subtraction, a new integer is formed and i now points to that, different than what tuple has.

However, if you were to put a mutable object and do similar things:

tup = ([1, 2, 3], [4, -12])

for i in tup:
    i[1] = 999

print(tup)

You get

([1, 999, 3], [4, 999])
Nimantha
  • 6,405
  • 6
  • 28
  • 69
1

A couple of things going on. A tuple is immutable and you're assigning the value (3, 2) to the type tuple .

tup = (3, 2)
for i in tup:
    i -= 1
print(tup)

Outputs:

(3, 2)

However you could do a list comprehension and cast it to tuple to get the expected result.

tup = (3,2)
tup = tuple([i - 1 for i in tup])
print(tup)

Outputs:

(2, 1)
l4sh
  • 321
  • 2
  • 7
1

Tuple is immutable.

try this, i think it will help you.

my_tuple = (3, 2)
new_list = []
for i in my_tuple:
    i -= 1
    new_list.append(i)
new_tuple = tuple(new_list)
print(new_tuple)
PrA-patel
  • 99
  • 1
  • 2
1

A brief introduction to python data structures should help you out here. Here's the gist

tuples are immutable i.e once created you cannot change the contents, you'll need to create a new one - you cannot modify the contents inplace similar to how strings work in python.

list makes sense but in your case it will still not work because you need to update the contents of the list when you do this:

tuple = (3, 2)
for i in tuple:
    i -= 1
print(tuple)

you are basically extracting the contents from the tuple and modifying the value but not storing it anywhere. Even if you use a list like this:

list = [3,2]
for i in list:
    i -= 1
print(list)

this will still not work as you are modifying a list item (a primitive type - int, string,etc.) which creates a new item but as it's not being stored it gets lost, when you print the list - it remains the same.

What we can do is modify the list as its mutable at runtime and update the contents like this:

list = [3, 2]
for idx, item in enumerate(list):
    list[idx] = item - 1
print(list)
Sanchit
  • 326
  • 3
  • 6