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?
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 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.
If anyone is interested in performance of the above solutions, here they are for 4000x4000 grids, from fastest to slowest:
izip
instead of zip
)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()
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With