Sam.Natale
Sam.Natale

Reputation: 50

How can I shorten a lot of if statements? (Python 3.x)

How can I shorten all of the if statements in the for loop? I am developing this for a college project. I cannot think of a way.

Basically the thing it should do is that if a certain location on a board does not equal a rock, then set it as a plant. The locations are a circle around the plant. Example:

N N N
N P N
N N N

if RainFall == 2:
    print("This summer has been a perfect summer, the plants have multiplied.")
    for Row in range(FIELDLENGTH):
        for Column in range(FIELDWIDTH):
            if Field[Row][Column] == PLANT:
                if Field[Row + 1][Column] != ROCKS:
                    Field[Row + 1][Column] = GOODSUMMER
                if Field[Row - 1][Column] != ROCKS:
                    Field[Row - 1][Column] = GOODSUMMER
                if Field[Row + 1][Column + 1] != ROCKS:
                    Field[Row + 1][Column + 1] = GOODSUMMER
                if Field[Row - 1][Column - 1] != ROCKS:
                    Field[Row - 1][Column - 1] = GOODSUMMER
                if Field[Row][Column + 1] != ROCKS:
                    Field[Row][Column + 1] = GOODSUMMER
                if Field[Row][Column - 1] != ROCKS:
                    Field[Row][Column - 1] = GOODSUMMER
                if Field[Row + 1][Column + 1] != ROCKS:
                    Field[Row + 1][Column - 1] = GOODSUMMER
                if Field[Row - 1][Column + 1] != ROCKS:
                    Field[Row - 1][Column + 1] = GOODSUMMER
                break

Upvotes: 1

Views: 411

Answers (2)

Noctis Skytower
Noctis Skytower

Reputation: 21991

We can only guess about the rest of your code, so included down below is a full implementation for testing purposes. To see your reworked code, check out the multiply_plants function. Instead of a having many if statements, it uses loops to check the area around a cell. You may also notice that is correctly checks for the bounds of each list so that IndexError exceptions do not occur.

#! /usr/bin/env python3
import random


FIELD_ROWS = 10
FIELD_COLUMNS = 10
EMPTY = ' '
PLANT = 'P'
ROCKS = 'R'
NEW_PLANT = 'N'


def main():
    field = create_field()
    show_field(field)
    multiply_plants(field, 2)
    replace_cells(field, NEW_PLANT, PLANT)
    show_field(field)


def create_field():
    field = []
    for _ in range(FIELD_ROWS):
        row = []
        for _ in range(FIELD_COLUMNS):
            row.append(random.choice([EMPTY] * 3 + [ROCKS] * 2 + [PLANT] * 1))
        field.append(row)
    return field


def show_field(field):
    width = max(map(len, field)) * 2 + 1
    print(f'/{"-" * width}\\')
    print('\n'.join(' '.join(['|'] + row + ['|']) for row in field))
    print(f'\\{"-" * width}/')


def multiply_plants(field, rainfall):
    # If there was enough rain, cause the plants to spread.
    if rainfall > 1:
        print('This summer has been a perfect summer;')
        print('the plants have multiplied!')
        # Find each space that already has a plant in it.
        for y, row in enumerate(field):
            for x, cell in enumerate(row):
                if cell == PLANT:
                    # Introduce a Y-axis offset to search up & down.
                    for y_offset in range(-1, 2):
                        y_index = y_offset + y
                        if 0 <= y_index < len(field):
                            # Introduce a X-axis offset to search left & right.
                            for x_offset in range(-1, 2):
                                if y_offset or x_offset:    # Skip zero offset.
                                    x_index = x_offset + x
                                    if 0 <= x_index < len(field[y_index]):
                                        # Spread plant to non-rock areas.
                                        if field[y_index][x_index] != ROCKS:
                                            field[y_index][x_index] = NEW_PLANT


def replace_cells(field, old, new):
    for y, row in enumerate(field):
        for x, cell in enumerate(row):
            if cell == old:
                field[y][x] = new


if __name__ == '__main__':
    main()

Upvotes: 1

instant
instant

Reputation: 696

Yeah, put your index permutations in a list and iterate over that. You can either define the list explicitely (more readable for beginners, but more error prone) or generate it with a comprehension. Explicit version first:

coord_shift = [(1, 0), (-1, 0), (1, 1), (-1, -1), (0, 1), (0, -1), (1, -1), (-1, 1)]
for Row in range(FIELDLENGTH):
    for Column in range(FIELDWIDTH):
        if Field[Row][Column] == PLANT:
            for i, j in coord_shift:
                if Field[Row + i][Column + j] != ROCKS:
                    Field[Row + i][Column + j] = GOODSUMMER

Some additional notes:

Recommended Python style is to use lowercase variable names for regular variables, uppercase guys are more meant for classes.

You don't need break.

The above catches your small mistake for Field[Row +1][Column -1].

The adventurous version I promised is:

coord_shift = [(i, j) for i in range(-1, 2) for j in range (-1, 2)]
coord_shift.drop((0, 0))

Upvotes: 2

Related Questions