我可以在Python中使用带条件的if-else语句使用嵌套的for循环吗? [英] Can I use a nested for loop for an if-else statement with multiple conditions in python?

查看:89
本文介绍了我可以在Python中使用带条件的if-else语句使用嵌套的for循环吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written a program that checks if a chess board is valid. In one part of my code I test, if the amounts of the pieces are correct.

count是字典,这是我要检查的电路板的清单.例如(b代表黑色,w代表白色):

count is dictionary, which is an inventory of the board I want to check. For example (b stands for black, w fo white):

count = {'bking': 1, 'wking': 1, 'bpawn': 3, 'bbishop': 1, 'wrook': 1, 'wqueen': 1}

可能的颜色和片段在列表中可用:

the possible colors and pieces are available in lists:

colors = ['b', 'w']
pieces = ['queen', 'rook', 'knight', 'bishop', 'pawn']

我有以下多重条件的if-else丑陋语句:

I have the following ugly if-else statement with multiple conditions:

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

有没有一种方法可以使用嵌套的for循环简化这种if-else结构?我意识到使用get()方法的行非常重复.我的想法是制作一个外部for循环,该循环遍历颜色,一个内部循环,遍历颜色.get()调用中的第一个参数是颜色列表中的项目与件列表中的项目的串联.有办法吗?

Is there a way to simplify this if-else structure with a nested for loop? I realized that the lines with the get() method are very repetitive. My idea was to make an outer for loop that iterates over the colors and an inner loop that iterates over the pieces. The first argument in the get() call is a concatenation of an item in the colors list with an item in the pieces list. Is there a way to do that?

还有另一种方法可以使if-else语句更具有Pythonic性吗?

Is there another way to make this if-else statement more pythonic?

这是我的第一次尝试:

for c in colors:
   for p in pieces[:4]:
      if count.get(c + p, 0) <= 2:
   if count.get(c + pieces[-1], 0) <= 8:
      return = True
   else:
      return = False

但这不起作用,我收到了SyntaxError或IndentationError.

But that does not work, I get a SyntaxError or an IndentationError.

似乎有效的原始代码如下:

My original code that seems to work is the following:

# chessDictValidator.py

def boardInventory(board):
    # Makes an inventory of the board to be evaluated.
    count = {}
    for value in board.values():
        count.setdefault(value, 0)
        count[value] += 1
    return count

def boardCounter(board):
    # Checks if amounts of pieces are valid.
    count = boardInventory(board)
    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

def fieldValidator(board):
    # Checks if the board contains valid fields.
    fieldOK = 0
    for key in board.keys():
        if key[0] in fieldInt and key[1] in fieldChar:
            fieldOK += 1
        else:
            return False
    if fieldOK == len(board):
        return True

def pieceValidator(board):
    # Checks if the pieces are spelled correctly.
    pieceOK = 0
    for value in board.values():
        if value[0] in pieceColor and value[1:] in pieces:
            pieceOK += 1
        else:
            return False
    if pieceOK == len(board):
        return True

def boardValidator(board):
    # Checks if the board is valid, depending on the tests above. Prints an error message when board is invalid.
    valid = 'This is a valid chess board!'
    invalid = 'Invalid chess board!'
    wrong = 'There is a wrong {0} in your board!'
    numPieces = 'There is something wrong with the allowed amount of pieces!'
    if fieldValidator(board) and pieceValidator(board) and boardCounter(board):
        print(valid)
    elif fieldValidator(board) == False:
        print(invalid, wrong.format('field'))
    elif pieceValidator(board) == False:
        print(invalid, wrong.format('piece'))
    elif boardCounter(board) == False:
        print(invalid, numPieces)

board = {
    '1b': 'bking',
    '6a': 'wqueen',
    '3f': 'brook',
    '4h': 'bknight',
    '3e': 'wking',
    '6d': 'wbishop',
    '2g': 'wbishop',
    '5c': 'bpawn',
    '8g': 'bpawn',
    '7b': 'bpawn',
}

fieldInt = ['1', '2', '3', '4', '5', '6', '7', '8']
fieldChar = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
pieceColor = ['b', 'w']
pieces = ['king', 'queen', 'knight', 'rook', 'bishop', 'pawn']

boardValidator(board)

推荐答案

首先,我建议将此检查外包给专用功能.

First, I would recommend outsourcing this check to a dedicated function.

第二,可以将dict与期望的最大值一起使用,并对 all()进行理解以更简洁地执行检查.

Second, you can use a dict with your expected max values, and use a comprehension with all() to perform the check more concisely.

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()
           )

如果您想稍微减少 max_counts 的详细程度,则可以尝试创建一个包含 king queen 基本计数的虚拟字典, rook 等,并使 max_counts 成为添加该列表的两个副本的结果,每个副本的前缀为'b'另一个是'w'.但是,如果这是整组作品,我认为没有必要.

If you want to be slightly less verbose with max_counts, you could try creating a dummy dict with the basic counts for king, queen, rook, etc., and make max_counts the result of adding two copies of that list, one with 'b' prefixed to each key and the other with 'w'. But I don't think thats necessary if this is the entire set of pieces.

还请注意,这可能不是棋盘验证的万无一失的方法.典当可能会升级为国王以外的任何其他类型的棋子,因此从技术上来说,拥有一个以上的女王或两个以上的白嘴鸦是可能的.

Also consider that this may not be a foolproof method of validation for your chessboard. Pawns may promote into any other type of piece besides king, so having more than one queen or more than two rooks is technically possible.

这篇关于我可以在Python中使用带条件的if-else语句使用嵌套的for循环吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆