Convert tuple to list and back
Asked Answered
Z

11

292

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?

Zedoary answered 30/4, 2013 at 9:35 Comment(3)
don't use a tuple, just use a list from the beginning. It might really slow down your code if your level is huge, if you have to keep converting themFritzie
how about going with lists instead of tuples from the very beginning?Crenel
@Zedoary btw just a compatibility note, you should use integer division // instead of just / because in Python 3, / will perform floating point division and screw up your code.Fritzie
E
381

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')
Espalier answered 6/5, 2014 at 14:27 Comment(2)
This is not working for me. If I run the code in the first block to convert the tuple t to a list by passing t to list(), I get an error message: "*** Error in argument: '(t)'" This seems to happen to me only while debugging. Still confused.Gabardine
@Gabardine that's because list is a debugger command, run p list(...) instead.Alkalize
L
90

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
Lieabed answered 30/4, 2013 at 9:38 Comment(1)
NumPy is the fundamental package for scientific computing with Python. NumPy's main object is the homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of positive integers.Lieabed
P
27

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.

Paraclete answered 30/4, 2013 at 9:37 Comment(0)
H
25

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
Habitforming answered 31/7, 2020 at 12:39 Comment(0)
C
20

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

Cheremkhovo answered 20/6, 2015 at 2:20 Comment(0)
S
16

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)
Southland answered 30/5, 2015 at 17:22 Comment(0)
T
5

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

Tyndale answered 30/4, 2013 at 9:35 Comment(2)
You should also write in this answer, that numpy will provide the fastest solution to working with this type of data.Fritzie
Of course you can use immutable data structures such as tuples even when you are manipulating data. The whole premise of functional programming and all that largely builds on persistence of data. But of course, in Python land you may want to go with the masses and mutate freely...Milter
B
5

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)
Beatitude answered 21/12, 2018 at 18:44 Comment(0)
K
2

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.

Koy answered 30/4, 2013 at 10:2 Comment(0)
S
2

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]]
Seasonseasonable answered 5/2, 2021 at 15:24 Comment(0)
U
1

In my case, I wanted to merge rows/ lists:

a = ['Tom', 'Dick', 'Harry']
b = ['20', '32', '14']
c = ['foo', 'bar', 'blah']
lines = [list(row) for row in zip(a, b, c)]
lines = [['Tom', '20', 'foo'], ...]
Unintentional answered 26/10, 2022 at 12:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.