如何将条件语句转换为简单表达式?这样回报复合收益是可以接受的做法吗?

问题描述

我正在做的练习是由一本书给出的,该书接受字典参数,并要求我给出True或False的返回值。我是Python 3的新手,作为学习的个人练习,我想将“作为棋盘的有效词典”的所有条件转换为单个返回值。我尚未实际测试此代码的错误,因为它尚未完成,但我确实通过我发现的https://extendsclass.com/python-tester.html在线验证器运行了它。

我想知道如何将下面的2个代码块转换为简单的表达式,以在下面的函数中的return语句中使用。您可以在下面看到,我已经将大多数表达式转换为带有“和”的返回值”,因为“所有表达式必须== True”

for pieces in dictionary.values():
    if all(pieces.startswith('b')) or \
         all(pieces.startswith('w')):
        return True
    else:
        return False

上面的代码块循环通过传递给“件”的字典键, 并分别比较每个键,以确定它是否以'b'或'w'开头。因此,如果任何键都不以“ b”或“ w”开头,则词典“ chessboard”为假,因为它包含不正确的部分。好的,我想我会发现一个错误,我将对其进行调查并尝试解决。好的,我注意到以上代码中的一些错误需要解决,我目前正在研究如何正确执行以上代码。

for square in dictionary:
    try:
        if int(square[:0]) <= 8 and \
            square[-1] <= 'h':
            return True
        else:
            return False
    except ValueError:
        return False

我在上面的代码块上工作了很长时间,但仍然不确定这是我想要执行的“最佳”实现。但是我还是个新人,尽我所能。 无论如何,它都会对字典键进行切片,并比较键中的第一个字符,以确保它不超过8,这是最大的“有效范围”;如果超出有效范围,它将返回false,而任何非int值显然会自动为False并返回通过“例外”。

然后,它对字典键进行切片以获取字典键的最后一个字符,并将其与

这里是当前函数,最后是测试字典:

def cBV(dic):                        # (c)hess(B)oard(V)alidator
    Err = 'Error: Invalid Board -'
    if not isinstance(dic,type({})):
        raise TypeError('Object passed to cBV is not of type <class dict>')
    
    chess_pieces = {'bk pieces': 0,'wh pieces': 0,'bk pawns': 0,'wh pawns': 0}

    # converts dictionary values into keys and assigns those keys "counn of values"      
    for squares,pieces in dic.items:
        if pieces.startswith('b'):                 # alt if pieces[:0] == 'b':
            if pieces.startswith('bpawn'):         # alt if pieces == 'bpawn':
                chess_pieces['bk pawns'] += 1
            chess_pieces['bk pieces'] += 1
        elif pieces.startswith('w'):
            if pieces.startswith('wpawn'):
                chess_pieces['wh pawns'] += 1
            chess_pieces['wh pieces'] += 1
        
    return 'wking' in dic.values() and \                
            'bking' in dic.values() and \
            chess_pieces['bk pieces'] <= 16 and \
            chess_pieces['wh pieces'] <= 16 and \ 
            chess_pieces['bk pawns'] <= 8 and \
            chess_pieces['wh pawns'] <= 8 and \ 
            


dict = {'8h': 'wking','2c': 'bking','3a': 'wpawn','3b': 'wpawn','3c': 'wpawn','3d': 'wpawn','3e': 'wpawn','3f': 'wpawn','3g': 'wpawn','3h': 'wpawn','4b': 'wpawn'}
test = cBV(dict)
print('Is this a valid chessboard? ' + str(test))

解决方法

您现在拥有的东西很好,您应该感到自豪-有更多新颖的技巧可以使事情变得更简洁,随着您对各种数据结构的工作方式的了解,您会逐渐习惯这些。 / p>

    for pieces in dictionary.values()
        if pieces.startswith('b') or \
             pieces.startswith('w'):
            return True
        else:
            return False

可以转换为单线

return all(
    piece.startswith('b') or piece.startswith('w')
    for piece in dictionary.values()
)

这有几件事。

  • all()函数采用任何可迭代对象,如果该可迭代对象中的所有值均为真,则返回True。如果甚至没有一个,它就会“短路”并返回False
  • 作为对all()的论点,我们给出了“理解”。理解本质上是形式为for的单行f(element) for element in iterable循环:对于迭代中的每个f(element),它执行的是element
    • 在我们的例子中,迭代器为dictionary.values(),它返回dictionary(此处为{{1)中的所有(但不包括键)。 }}。在这种情况下,这些是字符串。
    • 'wking','wpawn',...是我们为理解的每个“迭代”分配的每个元素。它会先运行piece,然后再运行piece = 'wking',等等。
    • piece = 'wpawn'是我们为每个piece.startswith('b') or piece.startswith('w')执行的功能。根据是否满足条件,这将输出pieceTrue
    • 您可以将理解内容括在方括号False中,以将其输出为常规列表。但是,如果您对诸如[]之类的函数提供一个理解,这就是我们在这里所做的,那么它将最终成为“生成器”,这是一个效率更高的对象,仅计算一个对象一次。就我们的目的而言,这并不重要。
    • 这种理解总体上产生了一个包含all()将会消耗的TrueFalse的系列。

与您的第二个代码段相似。您已经掌握了基础知识,但可以更加简洁。您的代码:

all()

可以变成

def allSquaresAreInRange(dictionary):
    for square in dictionary:
        try:
            if int(square[:0]) <= 8 and \
                pieces[-1] <= 'h':
                return True
            else:
                return False
        except ValueError:
            return False

在这里,我们利用一些东西:

  • 像以前一样,我们使用def allSquaresAreInRange(dictionary): try: return all( (1 <= int(row) <= 8) and ('a' <= col <= 'h') for (row,col) in dictionary ) except ValueError: return False ,并且像以前一样,我们使用理解。但是这次,我们直接遍历all()
    • 通过dictionary进行迭代的功能与通过dict进行迭代的功能相同。因此,我们正在迭代键dict.keys()
  • 每个键都是两个字符的字符串。字符串是可迭代的,就像列表一样,并且大多数可迭代的对象都有一个有趣的属性,称为“多重分配”:如果我们分配的变量与可迭代对象具有的元素数量一样多,那么这些元素就会被拆分。
      例如,
    • '8h','2c',...在功能上与(row,col) = '8h'row = '8h'[0]相同。在这两种情况下,我们只剩下col = '8h'[1]row = '8'
    • 如果两边的元素数量不匹配-例如,如果键只有一个字符或只有三个字符,则会生成col = 'h'。这样做的副产品是,如果没有发生此错误,则保证ValueErrorrow完全是一个字符长的字符串。
  • 我们的条件使用大于/小于符号检查col是否在1到8之间,以及row是否在A和H之间。这将再次返回colTrue
    • 您似乎已经发现,在不代表整数的对象上使用False也会 抛出int()
  • 此新代码段保留了您提出的ValueError / try块,因为它们工作得很好。

Python周围有一些文化,以“高效编写”代码为荣。就是说,看起来尽可能花哨的代码并遵循函数式编程范例。理解力以及exceptall()都是其中的重要部分,因此,对于他们的任何问题,它们可能都是“正确”的解决方案(如果可以写得简洁一点)。

类似地,片段

any()

几乎总是可以凝结为

if condition:
    return True
else:
    return False

(或return condition ,在return bool(condition)处理具有真实性但不是布尔值的值的情况下,例如condition或空列表或字符串)。如果可以的话,这是个好习惯(但同样,并不总是适用)。

不过,最重要的是,您的代码可以按您希望的方式工作,并且很清楚,您可以在几个月后重新使用它并找出什么您正在做,而为什么您正在那样做。在某些情况下,可以被编写为理解,但是这使它们变得极其复杂且难以理解-在这些情况下,最好不要将它们编写为理解,并且做得更冗长道路。在继续开发时,请记住这一点,您会做得很好。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...