Zhao_L Zhao_L - 1 month ago 9
Python Question

Modify a subset of a dict in Python

Hello guys: I have a quite trick problem in python now and I don't know how to fix it, hope any one could explain me this.

The problem is follows:

I have a dict(), let's call it D. The keys in D are pairs of integers (i, j) which denotes the coordinates of the center of the unit squares, and the value corresponding to (i, j) is one of the colors ('r', 'g', 'b').

In my program I have to frequently check if a 2x2 square are all 'red' and if so then change their color to 'blue', which I have to write:

if (D[(i, j)] == 'red'
and D[(i, j+1)] == 'red'
and D[(i+1, j)] == 'red'
and D[(i+1, j+1)] == 'red'):
D[(i, j)] = .. = 'blue'


Well, the real situation is more complicated and the above is only an example.

I have to write such type of codes many times: if all red, if all blue, if some blue some red, .... I'm getting crazy! SO I decided to write

block = [[D[(i,j)], D[(i, j+1)], D[(i, j+1)], D[(i+1, j+1)]]
if block == ['red', 'red', 'red', 'red']:
block = ['blue', 'blue', 'blue', 'blue']


of course this does not work because when reassigning values to block, the original set is not altered: the D[(i,j)]'s are still 'red'.

So my question is: how can I modify the subset efficiently in my situation? To be more precisely, I have to take some (key, value) pairs out of a dict, store them in temporary variables (or data structure), check and modify these variables, and hope to change the original dict also while I was changing the variables. But it always worked the other way than I expected.

Answer

Why aren't you just making functions?

def is_2x2red(squares,x,y):
    return (squares[(x,y)]=='r' and squares[(x,y+1)]=='r' and
            squares[(x+1,y)]=='r' and squares[(x+1,y+1)]=='r')

and one for assigning blue?

def blue2x2(squares,x,y):
    squares[(x,y)]='b'
    squares[(x,y+1)]='b' 
    squares[(x+1,y)]='b' 
    squares[(x+1,y+1)]='b'

then just use them all over?

if is_red2x2(squares,i,j): blue2x2(squares,i,j)

You can combine these to a single function to even shorten the calls.

edit If you need to make this work for more than 2x2, and just for future reference, the checks and assignments should be looped, for example the checks:

def is_red2x2(squares,x,y,n=1):
    return reduce(lambda x,y: = x*y,(squares[(i,j)]=='r' 
                    for i in range(x,x+n+1) for j in range(y,y+n+1)))
Comments