【问题标题】:How can I shorten a lot of if statements? (Python 3.x)如何缩短很多 if 语句? (Python 3.x)
【发布时间】:2017-03-09 15:46:10
【问题描述】:

如何缩短 for 循环中的所有 if 语句?我正在为一个大学项目开发​​这个。我想不出办法。

基本上它应该做的事情是,如果板上的某个位置不等于岩石,则将其设置为植物。这些位置是围绕植物的一个圆圈。示例:

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

【问题讨论】:

  • 很多方法。但是您想以一种有助于您以后开发它的方式对其进行概括。一个想法是有一种方法来评估一个正方形,并为它周围的所有正方形调用一次。像这样的东西需要面向对象编程。
  • 我不是 Python 人,但是在 OOP 中,有针对这种情况的命令模式。挖完:stackoverflow.com/a/1494532/5058677

标签: python-3.x


【解决方案1】:

是的,将您的索引排列放在一个列表中并对其进行迭代。您可以明确定义列表(对初学者来说更易读,但更容易出错)或使用理解生成它。显式版本优先:

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

一些补充说明:

推荐的 Python 风格是对常规变量使用小写的变量名,大写的人更适合类。

你不需要休息。

上面提到了Field[Row +1][Column -1] 的小错误。

我承诺的冒险版本是:

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

【讨论】:

    【解决方案2】:

    我们只能猜测您的其余代码,因此下面包含了用于测试目的的完整实现。要查看您重新编写的代码,请查看 multiply_plants 函数。它没有使用许多if 语句,而是使用循环来检查单元格周围的区域。您可能还会注意到,它正确检查了每个列表的边界,因此不会发生 IndexError 异常。

    #! /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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-15
      • 2022-11-23
      • 2012-04-06
      • 2012-07-05
      • 1970-01-01
      • 2012-04-25
      • 2017-05-06
      • 2018-08-19
      相关资源
      最近更新 更多