Python 如何简化这个很长的if语句?

Python 如何简化这个很长的if语句?,python,graphics,if-statement,modulus,simplification,Python,Graphics,If Statement,Modulus,Simplification,如何简化这个if语句?它是一个加号: 如果语句完成,则在x和y坐标处设置块 for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): if (x%5 == 2 or x%5 == 3 or x%5 == 4) and \ (y%5 == 2 or y%5 == 3 or y%5 == 4) and \ not(x%5 == 2 and y%5 == 2) and \

如何简化这个if语句?它是一个加号:

如果语句完成,则在x和y坐标处设置块

for y in range(MAP_HEIGHT):
    for x in range(MAP_WIDTH):
        if (x%5 == 2 or x%5 == 3 or x%5 == 4) and \
            (y%5 == 2 or y%5 == 3 or y%5 == 4) and \
            not(x%5 == 2 and y%5 == 2) and \
            not(x%5 == 4 and y%5 == 2) and \
            not(x%5 == 2 and y%5 == 4) and \
            not(x%5 == 4 and y%5 == 4):
            ...

有两个简单的修复:

  • 缓存
    x%5
    y%5

  • 在中使用
    ,或在康拉德的答案基础上使用chained
    ,您可以进一步简化:

    for y in range(MAP_HEIGHT):
        for x in range(MAP_WIDTH):
            lx = x % 5 # for local-x
            ly = y % 5 # for local-y
            if (1 < lx < 5 and 1 < y < 5 and 
               (lx, ly) not in ((2, 2), (4, 2), (2, 4), (4, 2))):
    
    范围内y的
    (地图高度):
    对于范围内的x(贴图宽度):
    lx=x%5#对于局部-x
    ly=y%5#对于局部y
    如果(1
    这是一样的:

    if (x % 5 == 3 and y % 5 > 1) or (y % 5 == 3 and x % 5 > 1): 
    

    康拉德的第二个答案:-

    cross_fields = [(2, 3), (3, 2), (3, 3), (3, 4), (4, 3)]
    
    for y in range(MAP_HEIGHT):
      for x in range(MAP_WIDTH):
        if (x % 5, y % 5) in cross_fields:
    
    可能是最好的

    然而,我将贡献:-

    for y in range(MAP_HEIGHT):
      for x in range(MAP_WIDTH):
        lx = x % 5
        ly = y % 5
        if (lx > 1 and ly == 3) or (ly > 1 and lx == 3):
    

    基本上,您正在平铺一个5x5二进制模式。这里有一个明确的表达:

    pattern = [[0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0],
               [0, 0, 1, 1, 1],
               [0, 0, 0, 1, 0]]
    
    for y in range(MAP_HEIGHT):
        for x in range(MAP_WIDTH):
            if pattern[x%5][y%5]:
               ...
    

    这是一种非常简单和通用的方法,可以很容易地修改模式。

    优化这样的逻辑函数的通用解决方案是一种简单的方法。您的真值表将是您想要的文字+形状,行和列是您的模块化测试。

    该死,您赢了。;-)但是请去掉多余的括号。除非我弄错了,否则OP的语句不会为例如x=1画块;y=3。我认为元组列表不正确。是否应该是(2,3)、(3,3)、(4,3)、(3,2)和(3,4)?(或者等等,你刚才是不是漏了一个not?)。在if语句完成的x和y坐标处设置了一个块。请不要添加注释。请更新问题以使其完整。请修正这个问题并删除评论。我很确定你可以通过使用一些智能切片来压缩这些内容,但是我有点太懒了,没有办法解决。哇。是你做的。。可读,我根本没有想过使用列表/元组。除了第一段代码有一些错误外,这两种方法都可以工作。最后一个耦合的条件语句不应该是(lX==4和lY==4),并且应该有一个lX!=0和lY!=0.@Azrathud:事实上,我觉得Dave的答案更好一些。不管怎样,谢谢你的更正。我认为使用元组是正确的做法。Daniel Roseman,&@Iain Galloway:这个解决方案和其他使用
    中的
    操作符的解决方案都受到这样一个事实的影响,即它们通过每个x和y的模坐标序列进行线性搜索。如果要这样做,通常使用键为
    (x%5,y%5)
    元组的
    集会更好更快。这样,不管这个集合是从原始的还是优化的
    if
    语句、位图模式,还是从坐标的显式
    列表或
    元组构建的,结果语句都将是setvar:
    中的
    if(x%5,y%5)。与martineau的答案如此相似?第一步应该是相似的,但卡诺图是一种提取覆盖这些情况所需的最小逻辑表达式的技术。(&@Iain Galloway):我的答案中使用的位图基本上是两个输入变量的K图(
    x%5
    y%5
    )--因此,是的,结果将与我的答案相同,但以一种完全不同(更简单的IMHO)的方式得出。
    for y in range(MAP_HEIGHT):
      for x in range(MAP_WIDTH):
        lx = x % 5
        ly = y % 5
        if (lx > 1 and ly == 3) or (ly > 1 and lx == 3):
    
    pattern = [[0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0],
               [0, 0, 1, 1, 1],
               [0, 0, 0, 1, 0]]
    
    for y in range(MAP_HEIGHT):
        for x in range(MAP_WIDTH):
            if pattern[x%5][y%5]:
               ...