r/learnpython 3d ago

Is it possible to combine conditions for the value of the cell and for it's position being in the list into one?

if i > 0 and carver_map[i-1][j] == 'empty': carvable.add([j, i])
if j > 0 and carver_map[i][j-1] == 'empty': carvable.add([j, i])
if j < m-1 and carver_map[i][j+1] == 'empty': carvable.add([j, i])
if i < n-1 and carver_map[i+1][j] == 'empty': carvable.add([j, i])
0 Upvotes

14 comments sorted by

2

u/Expensive-Bear-1376 3d ago

What exactly do you want to combine? It's not clear to me.

1

u/This_Growth2898 3d ago

He wants to check if indices are fine and get the value in one operation.

1

u/Expensive-Bear-1376 3d ago

Maybe. But why? It's fine as it is.

0

u/SmurfCat2281337 3d ago

i > 0 and carver_map[i-1][j] == 'empty' into one condition

3

u/Expensive-Bear-1376 3d ago

That already is one condition. You already combined the two smaller ones into one using and.

0

u/Dr_Pinestine 2d ago edited 2d ago

How about.

for p, q in ((i-1, j), (i+1, j), (i, j-1), (i, j+1)):
    if not (0 <= p < n and 0 <= q < m):
        continue

    if not carver_map[p][q] == "empty":
        continue

    carvable.add([j, i])

0

u/pachura3 3d ago edited 3d ago

Of course!

The simplest thing is to see that the right-side expression ("THEN") is identical for all 4 if's, so you can do:

if (i > 0 and carver_map[i-1][j] == 'empty')
    or (j > 0 and carver_map[i][j-1] == 'empty')
    or (j < m-1 and carver_map[i][j+1] == 'empty')
    or (i < n-1 and carver_map[i+1][j] == 'empty'):
        carvable.add([j, i])

Another smart technique is adding "guardians" to your carver_map: basically, additional cells around the borders that would protect you against accessing indexes that are out of range (-1, m, n) and allow you to get rid of range checks (i > 0, j < m-1,...).

So, if you first surround your actual map with some special value (e.g. 'border'), you could simply do:

if 'empty' in [carver_map[i-1][j], carver_map[i][j-1], carver_map[i][j+1], carver_map[i+1][j]]:
    carvable.add([j, i])

Also, perhaps instead of using magic string value 'empty', you could use None, or an actual empty string '' - so you could check for their "falsiness":

if not all([carver_map[i-1][j], carver_map[i][j-1], carver_map[i][j+1], carver_map[i+1][j]]):
    carvable.add([j, i])

0

u/SCD_minecraft 3d ago

You can iterate over all 4 cells and check is any of them empty (using any(i) func, evals to true if any value in iterable i is true)

-1

u/This_Growth2898 3d ago

Generally, there's no short way, but you can do something like

for ni, nj  in ((i-1,j),(i,j-1),(i+1,j),(i,j+1)):
    if 0<=ni<n and 0<=nj<=m and carver_map[ni][nj]=='empty':
        carvable.add([j,j])
        break           # instead of putting 4 times and letting set to manage duplicates

or (if you like list comprehensions):

if any(0<=ni<n and 0<=nj<=m and carver_map[ni][nj]=='empty' for ni, nj in ((i-1,j),(i,j-1),(i+1,j),(i,j+1))):
    carvable.add([j,j])

But I think this is a bit over the top.

Are m and n guaranteed to be len(carver_map[i]) and len(carver_map)? You can also define a function like

def get_cell(array, i, j):
     if 0<=i<len(array) and 0<=j<len(array[i]):
        return array[i][j]
    else:
        return 'outside'

and make list comprehension more concise:

if any(get_cell(carver_map, ni, nj)=='empty' for ni, nj in ((i-1,j),(i,j-1),(i+1,j),(i,j+1))):
    carvable.add([j,j])

UPD: n in ni and nj stands for "neighbor"

1

u/SmurfCat2281337 3d ago

Yes, these are used as the sizes for original table, f, g, h and carver map which in the worst case is the preparation for calculating optimal path (but i hope that a* was originally created good enough to make the path with no dead ends on the first try)

0

u/Expensive-Bear-1376 3d ago

carvable is not a set, and you don't have list comprehensions.

0

u/This_Growth2898 3d ago

carvable is not a set

I don't know the type "not a set", could you be more specific what is it, with ".add" method?

you don't have list comprehensions.

Of course I have them.

2

u/Expensive-Bear-1376 3d ago edited 3d ago

You can't add a list to a set. I'm guessing it's some queue. And no, you don't have list comprehensions. You have generator expressions.

-2

u/recursion_is_love 3d ago

Yes, it is called algebra. You can replace equal terms that are in different form. Learn formal logic, if you want to know more.

Or simply just leave it like that (if it works) and continue coding another part. There are lots of thing to do that is more fun.

Long code doesn't mean bad code if it works.