Reputation: 1943
I'm looking for a way to do the following:
TABLE=[table1,table2,table3]
TABLE_1=[table1_dup=list(table1),table2_dup=list(table2),table3_dup=list(table3)]
(this doesn't work; I'm just trying to explain my goal) so that I can access tablex and tablex_dup independently after performing batch operations on the whole TABLE and TABLE_1, which include table1, table2, ... and the duplicates.Thanks a lot!
EDIT: The sublists aren't necessarily named the same (table1, table2, table3). Actually, their names are quite different (e.g. up, down, left, right)
EDIT #2: I'm kinda new to this. Basically, here's my code:
up=["img1.png","img2.png"]
similar things for down, left and right.
table=[up,down,left,right]
Now using pygame:
for j in range(len(table)):
for i in range(len(table[j])):
table[j][i] = pygame.image.load(os.path.join(str(table[j][i])))
table_r[j][i] = pygame.image.load(os.path.join(str(table_r[j][i])))
table_r[j][i] = pygame.transform.flip(table_r[j][i],1,0)
This wouldn't work as there is no up_r, for example, that I could access. Only up.
Upvotes: 2
Views: 163
Reputation: 35059
On the more general issues raised in the comments and by your edits - it seems very much like a list of lists isn't the right data structure for your logic here. A list is usually indicated when you can have arbitrarily many 'rows' in your table - it seems you always have exactly four. A tuple is better in this case - it is kindof like a list, except it is set up more deliberately for things that don't change. And, even better, since you want to address your four things by name, there's a standard Python class called collections.namedtuple
that makes this easy.
You would define a Table class like this:
Table = namedtuple('Table', ['up', 'down', 'left', 'right'])
And then you create your first table like this:
table = Table(up=["img1.png","img2.png"], down=..., left=..., right=...)
This lets you get your 'up' list as table.up
, which means when you do a deepcopy into table_r
per Constantinius' answer, these names come with it for free. And it also lets you iterate over it in exactly the same way as your list:
for i in range(len(table)):
for j in range(len(table[i])):
...
However, note that iterating over range(len(iterable))
is usually not necessary - since you're using the index to look up values from your two tables simultaneously, what you really want is a combination of the builtin functions enumerate
and zip
:
for row, row_r in zip(table, table_r):
for i, (val, val_r) in enumerate(zip(row, row_r)):
row[i] = pygame.image.load(os.path.join(str(val)))
row_r[i] = pygame.image.load(os.path.join(str(val_r)))
You only need the index to assign into the lists, since rebinding val
and val_r
inside the inner loop won't work. Since you don't use j
as anything other than a lookup, you don't need it at all.
But this also brings up the one caviat of using a namedtuple - the one thing it can't do that you might care about is change an attribute of the tuple after it is created:
>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x = 2
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
p.x = 2
AttributeError: can't set attribute
In your case, this means you can't reassign table.up
to a new list at any point (you can still change the list itself, though, through its mutation methods and slice assignment) - if you need that, you're best off coding your own class for this.
Upvotes: 1
Reputation: 2804
TABLE_1 = [ table[:] for table in TABLE ]
This only suits your purpose if the tables in TABLE do only contain immutables.
Upvotes: 1
Reputation: 35039
I think, the deepcopy
function suits fine in this occasion.
from copy import deepcopy
...
TABLE_1 = deepcopy(TABLE)
Upvotes: 8