繁体   English   中英

在 Python 的 itertools 模块中使用 zip_longest 的代码行

[英]line of code using zip_longest in itertools module for Python

我知道这是一个非常具体的问题,但我希望它也能帮助其他人。 能否请您帮助我完全理解 Python 中的这行代码:

    new_word = ''.join(c if c == g else '_' for c,
                       g in zip_longest(correct, GUESS, fillvalue='_'))

我很快就会进行代码审查,这是我唯一不完全理解的代码行。 我不熟悉在一行中全部使用“if”和“for”。 如何在多个语句中重写它?

这是 zip_longest Python 文档,但我仍然不明白它在上述上下文中的工作原理

def zip_longest(*args, fillvalue=None):
    # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
    iterators = [iter(it) for it in args]
    num_active = len(iterators)
    if not num_active:
        return
    while True:
        values = []
        for i, it in enumerate(iterators):
            try:
                value = next(it)
            except StopIteration:
                num_active -= 1
                if not num_active:
                    return
                iterators[i] = repeat(fillvalue)
                value = fillvalue
            values.append(value)
        yield tuple(values)

在方法调用中使用单行for语句称为生成器表达式,如PEP 289中所定义。 您可以按如下方式重写此表达式:

new_word = ''
for c, g in zip_longest(correct, GUESS, fillvalue='_'):
    if c == g:
        new_word += c
    else:
        new_word += '_'

简而言之, new_word的长度将与correctGUESS中较长的一个长度相同,并且将由所有位置的下划线字符组成,除了那些correctGUESS相同的位置。

您问题中的代码将 2 个可迭代对象(可能是字符串)压缩在一起,以便比较每对字符,选择要返回的字符,并将结果字符连接回字符串。 看起来像是刽子手风格的文字游戏中的代码。

您可以以稍长的形式完成同样的事情,并从循环中断开连接以更好地了解它是如何工作的。 以下是使用单词“hangman”和“winger”的示例(您将在下面找到代码示例的详细说明):

from itertools import zip_longest

chars = []
correct = 'hangman'
guess = 'winger'
for c, g in zip_longest(correct, guess, fillvalue='_'):
    if c == g:
        chars.append(c)
    else:
        chars.append('_')

print(chars)
# ['_', '_', 'n', 'g', '_', '_', '_']

word = ''.join(chars)
print(word)
# __ng___      

对于每次迭代, c if c == g else '_'代码检查每个单词中相同位置的字符是否相同。 如果字符相同,则将匹配的字符添加到输出列表中。 如果字符不同,则在输出列表中添加下划线。 在我们的示例单词的第一次迭代中, c是“h”, g是“w”,因此字符不同,并且在输出列表中添加了下划线。 由于每个示例单词中的第三个字符都是“n”,因此在第三次迭代时将“n”添加到输出列表中。 fillvalue中的zip_longest确保您完全遍历对中最长的单词并添加下划线字符以替换较短单词中缺失的字符。

生成的输出列表将是['_', '_', 'n', 'g', '_', '_', '_'] 这是因为每个示例单词中的前两个字符不同(导致下划线),第三个和第四个字符相同(导致匹配字符),第五个和第六个字符不同,并且“中的最后一个字符hangman”与填充值进行比较,因为“ fillvalue ”比“hangman”短一个字符。

最后, ''.join()将字符列表连接成一个看起来像"__ng___"的字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM