Convert tuple to list and back

PythonListTuples

Python Problem Overview


I'm currently working on a map editor for a game in pygame, using tile maps. The level is built up out of blocks in the following structure (though much larger):

level1 = (
         (1,1,1,1,1,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,1,1,1,1,1))

where "1" is a block that's a wall and "0" is a block that's empty air.

The following code is basically the one handling the change of block type:

clicked = pygame.mouse.get_pressed()
if clicked[0] == 1:
    currLevel[((mousey+cameraY)/60)][((mousex+cameraX)/60)] = 1

But since the level is stored in a tuple, I'm unable to change the values of the different blocks. How do I go about changing the different values in the level in an easy manner?

Python Solutions


Solution 1 - Python

Convert tuple to list:

>>> t = ('my', 'name', 'is', 'mr', 'tuple')
>>> t
('my', 'name', 'is', 'mr', 'tuple')
>>> list(t)
['my', 'name', 'is', 'mr', 'tuple']

Convert list to tuple:

>>> l = ['my', 'name', 'is', 'mr', 'list']
>>> l
['my', 'name', 'is', 'mr', 'list']
>>> tuple(l)
('my', 'name', 'is', 'mr', 'list')

Solution 2 - Python

You have a tuple of tuples.
To convert every tuple to a list:

[list(i) for i in level] # list of lists

--- OR ---

map(list, level)

And after you are done editing, just convert them back:

tuple(tuple(i) for i in edited) # tuple of tuples

--- OR --- (Thanks @jamylak)

tuple(itertools.imap(tuple, edited))

You can also use a numpy array:

>>> a = numpy.array(level1)
>>> a
array([[1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 1, 1, 1, 1, 1]])

For manipulating:

if clicked[0] == 1:
    x = (mousey + cameraY) // 60 # For readability
    y = (mousex + cameraX) // 60 # For readability
    a[x][y] = 1

Solution 3 - Python

You can have a list of lists. Convert your tuple of tuples to a list of lists using:

level1 = [list(row) for row in level1]

or

level1 = map(list, level1)

and modify them accordingly.

But a numpy array is cooler.

Solution 4 - Python

To convert tuples to list

(Commas were missing between the tuples in the given question, it was added to prevent error message)

Method 1:

level1 = (
     (1,1,1,1,1,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,1,1,1,1,1))

level1 = [list(row) for row in level1]

print(level1)

Method 2:

level1 = map(list,level1)

print(list(level1))

Method 1 took --- 0.0019991397857666016 seconds ---

Method 2 took --- 0.0010001659393310547 seconds ---

Solution 5 - Python

Since Python 3.5 (PEP 448 -- Additional Unpacking Generalizations) one can use the following literal syntax to convert a tuple to a list:

>>> t = (1,2,3)
>>> lst = [*t]
>>> lst
[1, 2, 3]
>>> *lst,  # back to tuple
(1, 2, 3)

A list comprehension can be use to convert a tuple of tuples to a list of lists:

>>> level1 = (
...      (1,1,1,1,1,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,0,0,0,0,1),
...      (1,1,1,1,1,1))
>>> level1_list = [[*row] for row in level1]
>>> level1_list
[[1, 1, 1, 1, 1, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 0, 0, 0, 0, 1], 
 [1, 1, 1, 1, 1, 1]]
>>> *((*row,) for row in level1_list),
((1, 1, 1, 1, 1, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 0, 0, 0, 0, 1), 
 (1, 1, 1, 1, 1, 1))
>>> _ == level1
True

Solution 6 - Python

Why don't you try converting its type from a tuple to a list and vice versa.

level1 = (
     (1,1,1,1,1,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,1,1,1,1,1))

print(level1)

level1 = list(level1)

print(level1)

level1 = tuple(level1)

print(level1)

Solution 7 - Python

Both the answers are good, but a little advice:

Tuples are immutable, which implies that they cannot be changed. So if you need to manipulate data, it is better to store data in a list, it will reduce unnecessary overhead.

In your case extract the data to a list, as shown by eumiro, and after modifying create a similar tuple of similar structure as answer given by Schoolboy.

Also as suggested using numpy array is a better option

Solution 8 - Python

List to Tuple and back can be done as below

import ast, sys
input_str = sys.stdin.read()
input_tuple = ast.literal_eval(input_str)

l = list(input_tuple)
l.append('Python')
#print(l)
tuple_2 = tuple(l)

# Make sure to name the final tuple 'tuple_2'
print(tuple_2)

Solution 9 - Python

You could dramatically speed up your stuff if you used just one list instead of a list of lists. This is possible of course only if all your inner lists are of the same size (which is true in your example, so I just assume this).

WIDTH = 6
level1 = [ 1,1,1,1,1,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,1,1,1,1,1 ]
print level1[x + y*WIDTH]  # print value at (x,y)

And you could be even faster if you used a bitfield instead of a list:

WIDTH = 8  # better align your width to bytes, eases things later
level1 = 0xFC84848484FC  # bit field representation of the level
print "1" if level1 & mask(x, y) else "0"  # print bit at (x, y)
level1 |= mask(x, y)  # set bit at (x, y)
level1 &= ~mask(x, y)  # clear bit at (x, y)

with

def mask(x, y):
  return 1 << (WIDTH-x + y*WIDTH)

But that's working only if your fields just contain 0 or 1 of course. If you need more values, you'd have to combine several bits which would make the issue much more complicated.

Solution 10 - Python

Just using the command list did not work for me.

if you have a tuple just iterate until you have the elements there are necessary and after that append to a list. And if you go to the element level you can change it easily.

input:

level1 = (
         (1,1,1,1,1,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,0,0,0,0,1),
         (1,1,1,1,1,1))

level1_as_list=[]
for i in level1:
    inside_list=[]
    for j in i:
        inside_list.append(j)
    level1_as_list.append(inside_list)

print(level1_as_list)enter code here

output:

[[1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1]]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2133308View Question on Stackoverflow
Solution 1 - PythonKhonixView Answer on Stackoverflow
Solution 2 - PythonpradyunsgView Answer on Stackoverflow
Solution 3 - PythoneumiroView Answer on Stackoverflow
Solution 4 - PythonAravind KrishnakumarView Answer on Stackoverflow
Solution 5 - PythonAXOView Answer on Stackoverflow
Solution 6 - PythonTheRedstoneLemonView Answer on Stackoverflow
Solution 7 - PythontanzilView Answer on Stackoverflow
Solution 8 - PythonVijay RangarajanView Answer on Stackoverflow
Solution 9 - PythonAlfeView Answer on Stackoverflow
Solution 10 - PythonPedro DuqueView Answer on Stackoverflow