在python中,是否可以对带有多个条件的if-else语句使用嵌套for循环?

在python中,是否可以对带有多个条件的if-else语句使用嵌套for循环?,python,if-statement,conditional-statements,Python,If Statement,Conditional Statements,我写了一个程序,检查棋盘是否有效。在我的代码的一部分中,我测试了片段的数量是否正确 count是dictionary,这是我要检查的板的清单。例如(b代表黑色,w代表白色): 列表中列出了可能的颜色和颜色: colors = ['b', 'w'] pieces = ['queen', 'rook', 'knight', 'bishop', 'pawn'] 我有以下带有多个条件的丑陋的if-else语句: if count['bking'] == 1 and \ count['wking

我写了一个程序,检查棋盘是否有效。在我的代码的一部分中,我测试了片段的数量是否正确

count是dictionary,这是我要检查的板的清单。例如(b代表黑色,w代表白色):

列表中列出了可能的颜色和颜色:

colors = ['b', 'w']
pieces = ['queen', 'rook', 'knight', 'bishop', 'pawn']
我有以下带有多个条件的丑陋的if-else语句:

if count['bking'] == 1 and \
    count['wking'] == 1 and \
    count.get('bqueen', 0) <= 2 and \
    count.get('wqueen', 0) <= 2 and \
    count.get('bpawn', 0) <= 8 and \
    count.get('wpawn', 0) <= 8 and \
    count.get('brook', 0) <= 2 and \
    count.get('wrook', 0) <= 2 and \
    count.get('bknight', 0) <= 2 and \
    count.get('wknight', 0) <= 2 and \
    count.get('bbishop', 0) <= 2 and \
    count.get('wbishop', 0) <= 2 and \
    len(board) <= 32:
        return True
    else:
        return False
如果计数['bking']==1且\
计数['wking']==1和\

count.get('bqueen',0)首先,我建议将此检查外包给专门的功能

其次,您可以使用带有预期最大值的dict,并使用
all()
的理解来更简洁地执行检查

max_counts = {
    'bking': 1,
    'bqueen': 1,
    'brook': 2,
    'bknight': 2,
    'bbishop': 2,
    'bpawn': 8,
    'wking': 1,
    'wqueen': 1,
    'wrook': 2,
    'wknight': 2,
    'wbishop': 2,
    'wpawn': 8
}

def board_is_valid(count, board):
    return len(board) <= 32 and all(
               count[piece] <= ct 
               for (piece, ct) in max_counts.items()
           )
最大计数={
"bking":1,,
"bqueen":1,,
布鲁克:2,
"bknight":2,,
"bbishop":2,,
“b黎明”:8,
"工作":1,,
“女皇”:1,
"wrook":2,,
"wknight":2,,
"wbishop":2,,
“wpawn”:8
}
def板_有效(计数,板):

return len(board)一种简单的方法是对每个类别的最大值进行编码。唯一的特殊情况是必须有一个国王。不要将
棋子
作为
列表
,而是将棋子映射到游戏开始时的实例数:

pieces = {'queen': 1, 'rook': 2, 'knight': 2, 'bishop': 2, 'pawn': 8, 'king': 1}
其次,通过连接关键点,您的生活变得更加复杂。我建议制作一个嵌套字典,或一个包含两个字典的列表,分别包含黑白部分:

count = {'b': {'king': 1, 'pawn': 3, 'bishop': 1},
         'w': {'king': 1, 'rook': 1, 'queen': 1}}
检查现在容易多了。首先,验证
count
中每个字典的键是否是允许键的子集。您可以使用以下事实来执行此操作:
dict.keys
返回类似于
集的对象:

count['b'].keys() < pieces.keys()
最后,检查董事会上是否有国王:

count['b'].get('king') == 1
您不应该使用
count['b']['king']
,因为当电路板上没有king时,这将引发
KeyError
。返回
False
,与您对所有其他无效电路板所做的一样,更加一致

假设您使用我建议的
count
结构,我将如何编写支票:

def validate(count):
    def check_side(side):
        return side.keys() < pieces.keys() and all(pieces[k] >= v for k, v in side.items()) and side.get('king') == 1
    return all(check(v) for v in count.values())
def验证(计数):
def检查_侧(侧):
返回side.keys()=v代表k,v在side.items()中)和side.get('king')==1
返回全部(检查count.values()中的v)
运算符
以及
所有
都短路,因此如果答案为
False
,则会尽早返回


还请注意,使用这种方法,您不再需要
颜色
。信息存储在
count.keys()
中。信息冗余通常不是一个好主意。

我认为,嵌套for循环是最好的方法。我不明白你为什么不继续这种方法。有帮助吗?
len(board)@KarlKnechtel在我的代码板中代表给定的字段和给定板的片段,例如:board={'1b':'bking','8c':'bknight','4a':'wking','6c':'wqueen','5d','brook','4g':'bbishop'}。因为每个玩家都有16个棋子,棋盘字典必须有少于或等于32个棋子。绿斗篷:谢谢。你说得对,说得好。这意味着,我必须将皇后、车、主教和骑士的max_计数值提高1。这将是万无一失的,对吗?绿色斗篷男:看起来很优雅,但我有个问题。在我的代码中,count是一本字典,上面有我棋盘上的棋子。当bqueen消失后,你的函数将导致一个索引器…我将发布我的原始代码,这样你就可以明白我的意思了。@aurumpurum在
for
子句之后再添加一点理解:
if piece in count
绿斗篷盖:谢谢,你的函数似乎工作正常!只是出于兴趣:您在功能板中使用的概念的名称是什么?\u is\u valid()?你说这是一种理解,但条件的顺序,for子句和第二个条件在我看来似乎与我预期的完全不同。想了解更多信息…这是一个生成器理解(类似于列表理解,但没有方括号),作为函数
all()
的参数提供。理解的格式符合理解的一般格式:
在iterable if条件下输出项目
。在这种情况下,每个项目的输出只是
count[piece]的结果。这个代码建议在我看来很优雅,疯狂的物理学家!因为我要验证的板是扁平字典,所以我必须找出如何将它们转换为嵌套字典,以利用您的解决方案。有没有一种类似蟒蛇的方法?我只有一个丑陋的非pythonic解决方案:
用于扁平化的.items()中的k,v:nested[k[0]][k1:]=v
@aurumpum。听起来你应该问另一个问题。请记住,pythonic和unpythonic是非常主观的,谢谢。我试过你的代码:[k1:]中是否有输入错误,或者这是正确的?它对我不起作用:输入错误:
[k[1:]
count['b'].keys() < pieces.keys()
all(pieces[k] >= v for k, v in count['b'].items())
count['b'].get('king') == 1
def validate(count):
    def check_side(side):
        return side.keys() < pieces.keys() and all(pieces[k] >= v for k, v in side.items()) and side.get('king') == 1
    return all(check(v) for v in count.values())