Maximilian A. Graves
Maximilian A. Graves

Reputation: 72

Swapping objects in tuples - python

I have tuples in the form of:

a[i][j][k]

k ∈ [0,1] a is made up of objects T, that are included in a list teams.

What I want, is to swap the position of all pairs a[i][j][0] and a[i][j][1]. so:

a[i][j][0], a[i][j][1] = a[i][j][1], a[i][j][0]

As a is a tuple, I understand it is immutable, which is the reason that this does not work:

for i in range(0, len(teams)-1):
    for j in range(0, len(teams)/2):
        a[i][j][0],a[i][j][1] = a[i][j][1],a[i][j][0]

I have tried converting a to a list (L = list(a)), but without success.

Can somebody help me with suggestions? Sorry in case my nomenclatur is not perfect yet, this is my first question on SO :)

Thanks

Upvotes: 3

Views: 1041

Answers (3)

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

let's say a is a tuple of tuples of tuples.

I would

  • convert it to a list of lists of lists
  • do whatever I want
  • convert it back to the original format if needed

example:

a = (((1,2),(3,4)),((10,20),(30,40)))

a_as_list = [[list(x) for x in b] for b in a]

print(a_as_list)

# now manipulate elements:

a_as_list[0][0] = [a_as_list[0][0][1],a_as_list[0][0][0]]

a_as_tuple = tuple(tuple(tuple(x) for x in b) for b in a_as_list)


print(a_as_tuple)

result:

[[[1, 2], [3, 4]], [[10, 20], [30, 40]]]
(((2, 1), (3, 4)), ((10, 20), (30, 40)))

as you see, the tuples were converted to list, worked on, then converted back to tuples

EDIT: if a is a list of list of tuples you cannot do:

a[i][j][0], a[i][j][1] = a[i][j][1], a[i][j][0]

but you can recreate the inner tuple:

a[i][j] = a[i][j][1],a[i][j][0]

Upvotes: 4

Eric Duminil
Eric Duminil

Reputation: 54223

Problem

Tuples are immutables indeed. a might be a list, or even a list of lists. So this code:

L = list(a)

won't change anything. The problem appears to be that a is a list of lists of tuples. a[i][j] is a tuple, and it's not possible to assign new values to it:

>>> t = ('a', 'b')
>>> t[0] = 'b'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Possible solution

If you're working with 3-D matrices, numpy could probably help you. It supports advanced indexing and slicing:

>>> import numpy as np
>>> table = np.arange(18).reshape(3,3,2)
>>> table
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11]],

       [[12, 13],
        [14, 15],
        [16, 17]]])
>>> table[:, :, [0, 1]] = table[:, :, [1, 0]]
>>> table
array([[[ 1,  0],
        [ 3,  2],
        [ 5,  4]],

       [[ 7,  6],
        [ 9,  8],
        [11, 10]],

       [[13, 12],
        [15, 14],
        [17, 16]]])

Elements inside the matrix don't have to be numbers, they could be any objects:

>>> class T(str):
...   pass
... 
>>> T('test')
'test'
>>> m = np.array([[(T(1), T(2))],[(T(3), T(4))]])
>>> m[:, :, [0, 1]] = m[:, :, [1, 0]]
>>> m
array([[['2', '1']],

       [['4', '3']]], 
      dtype='<U1')

Upvotes: 1

xssChauhan
xssChauhan

Reputation: 2838

We can simply do this using Python's reversed

a[j][k] = tuple(reversed(a[j][k]))

Upvotes: 1

Related Questions