Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I, in python, iterate over multiple 2d lists at once, cleanly?

Tags:

If I'm making a simple grid based game, for example, I might have a few 2d lists. One might be for terrain, another might be for objects, etc. Unfortunately, when I need to iterate over the lists and have the contents of a square in one list affect part of another list, I have to do something like this.

for i in range(len(alist)):     for j in range(len(alist[i])):         if alist[i][j].isWhatever:             blist[i][j].doSomething() 

Is there a nicer way to do something like this?

like image 708
Eugene M Avatar asked Oct 09 '08 20:10

Eugene M


People also ask

How do you iterate through two lists at the same time in Python?

Iterate over multiple lists at a time We can iterate over lists simultaneously in ways: zip() : In Python 3, zip returns an iterator. zip() function stops when anyone of the list of all the lists gets exhausted. In simple words, it runs till the smallest of all the lists.

How do I iterate a 2D list?

How do you iterate through a 2D array? In order to loop over a 2D array, we first go through each row, and then again we go through each column in every row. That's why we need two loops, nested in each other. Anytime, if you want to come out of the nested loop, you can use the break statement.


2 Answers

If anyone is interested in performance of the above solutions, here they are for 4000x4000 grids, from fastest to slowest:

  • Brian: 1.08s (modified, with izip instead of zip)
  • John: 2.33s
  • DzinX: 2.36s
  • ΤΖΩΤΖΙΟΥ: 2.41s (but object initialization took 62s)
  • Eugene: 3.17s
  • Robert: 4.56s
  • Brian: 27.24s (original, with zip)

EDIT: Added Brian's scores with izip modification and it won by a large amount!

John's solution is also very fast, although it uses indices (I was really surprised to see this!), whereas Robert's and Brian's (with zip) are slower than the question creator's initial solution.

So let's present Brian's winning function, as it is not shown in proper form anywhere in this thread:

from itertools import izip for a_row,b_row in izip(alist, blist):     for a_item, b_item in izip(a_row,b_row):         if a_item.isWhatever:             b_item.doSomething() 
like image 86
DzinX Avatar answered Nov 13 '22 00:11

DzinX


I'd start by writing a generator method:

def grid_objects(alist, blist):     for i in range(len(alist)):         for j in range(len(alist[i])):             yield(alist[i][j], blist[i][j]) 

Then whenever you need to iterate over the lists your code looks like this:

for (a, b) in grid_objects(alist, blist):     if a.is_whatever():         b.do_something() 
like image 22
Robert Rossney Avatar answered Nov 13 '22 01:11

Robert Rossney