概念化分解枚举的列表理解

Conceputalize breaking down a list comprehension of enumerate

我从这里开始,喜欢列表理解。我发现下面这行代码用于将字符串中的所有其他字母大写的练习题,这对我来说很有意义。我希望得到帮助的问题是弄清楚如何在没有列表理解的情况下正常编写此代码(for 循环、if 语句等初学者的东西)。

这是我开始时要分解的代码:

s = input('Please enter a string: ')
answer = ''.join(char.upper() if idx % 2 else char.lower() for idx, char in enumerate(s))
print(answer)

下面是我认为可以重现上述代码的正确代码:

s = input('Please enter a string: ')
for idx, char in enumerate(s):
    if idx % 2:
        s = char.upper()
    else:
        s = char.lower()
    answer = ''.join(s)
print(answer)

如果我输入 Hello,我应该得到 hElLo,但我得到的却是 o

对于如何在此处进行操作的任何建议或提示,我将不胜感激。谢谢!

从技术上讲,您使用的是 generator expression, and not a list comprehension。但是在这种情况下结果是相似的。

您正在将输入读取到 s,但随后您在每次迭代中重新分配 s,然后您加入 s

您需要一个不同的变量。对于输入和大写列表。生成器表达式所做的是一次 return 一个值,而不是一次构建整个大写列表。但是这里需要声明一下。

此外,在每次迭代中都分配答案没有意义,join 是您需要做的最后一件事,一旦您准备好大写列表。

这应该有效:

toCapitalize = input('Please enter a string: ')
capitalizedList = []

for idx, char in enumerate(toCapitalize):
    if idx % 2:
        capitalizedList.append(char.upper())
    else:
        capitalizedList.append(char.lower())

answer = ''.join(capitalizedList)
print(answer)

如果这有帮助,我试着在下面反映生成器表达式的哪一行:

for idx, char in enumerate(toCapitalize):            # for idx, char in enumerate(s)
    if idx % 2: capitalizedList.append(char.upper()) # char.upper() if idx % 2
    else: capitalizedList.append(char.lower())       # else char.lower()
answer = ''.join(capitalizedList)                    # answer = ''.join()

同样,capitalizedList 变量隐含在生成器表达式或列表解析中。

生成器表达式

要了解生成器表达式,请看这段代码:

capitalize = 'hello'
generator = (char.upper() if idx % 2 else char.lower() for idx, char in enumerate(capitalize))
print(next(generator)) # h
print(next(generator)) # E
print(next(generator)) # l
print(next(generator)) # L
print(next(generator)) # o
print(next(generator)) # raises a StopIteration exception, we've reached the end.

每次调用 next() 都会即时计算下一次迭代的结果。当你有大列表时,这比一次构建整个列表更节省内存。在您的情况下,对 join() 的调用会消耗所有生成器,并加入值 returned.

作为列表理解

您的代码作为列表理解将是:

s = input('Please enter a string: ')
answer = ''.join([ char.upper() if idx % 2 else char.lower() for idx, char in enumerate(s) ])
print(answer)

正如我上面所解释的,不同之处在于我们一次构建一个完整的列表,生成器一次只 returning 一个值。

您的代码作为生成器

最后,为了在技术上正确,您的代码将等同于此:

def generator(s):
    for idx, char in enumerate(s):
        if idx % 2:
            yield char.upper()
        else:
            yield char.lower()

answer = ''.join(generator(s))
print(answer)

这就是您在 Python 中构建发电机的方式。