我能做一个列表理解,在for循环后附加一个值吗

2024-10-03 11:20:00 发布

您现在位置:Python中文网/ 问答频道 /正文

s = "lallalaiial" 
subs = []

for g in range(len(s)):
    for o in range(g, len(s)):
        substring = s[g:o+1]
        passable = True
        for v in range(len(substring)):
            if(substring[v] == "i"):
                passable = False
        if(passable):
            subs.append(substring)

print(subs)

我能为for循环做一个列表理解吗?只有在最后一个for循环检查了列表后,才应向列表中添加新值。我不想删除最后一个for循环-即使没有它也可以获得相同的结果。在


Tags: infalsetrue列表forlenifrange
3条回答

既然你想保持最内部的循环,你可以这样做:

subs = [ s[g:o+1] for g in range(len(s)) for o in range(g,len(s)) if all( [s[g:o+1][v]!="i" for v in range(len(s[g:o+1]))] ) ]

由于您使用passable标志只是为了测试i是否在当前子串中,因此可以使用in运算符对以下列表进行理解:

[s[g:o+1] for g in range(len(s)) for o in range(g, len(s)) if 'i' not in s[g:o+1]]

这和您的代码都将输出:

['l', 'la', 'lal', 'lall', 'lalla', 'lallal', 'lallala', 'a', 'al', 'all', 'alla', 'allal', 'allala', 'l', 'll', 'lla', 'llal', 'llala', 'l', 'la', 'lal', 'lala', 'a', 'al', 'ala', 'l', 'la', 'a', 'a', 'al', 'l']

列表理解是所有关于附加到for循环中的列表(在开始时创建列表,结果返回该列表),但是您需要先转换一下逻辑。在

列表理解基本上是一系列嵌套循环和if过滤器,以及一个确定要附加的值的表达式:

for ... in ...:
    if ...:
        for ... in ...:
            expression_generating_value_to_append

至少有一个循环,零个或多个if过滤器和其他循环。如果你能把你的代码转换成这样的结构,你就可以把它变成一个列表理解。在

你的代码还没有完全到位,因为你已经做到了

^{pr2}$

但这很容易转化为一个简单的in包容测试:

if "i" not in s[g:o + 1]:
    subs.append(s[g:o + 1])

这基本上是一样的;如果字符"i"不在子串中,那么子串是可以通过的,并且可以附加:

所以现在你有了

subs = []

for g in range(len(s)):
    for o in range(g, len(s)):
        if "i" not in s[g:o+1]:
            subs.append(s[g:o+1])

可以转换为列表理解;使用相同的循环和if测试,但将subs.append()中的部分移到前面;这是在输出列表中生成每个值的部分:

subs = [
    s[g:o+1]
    for g in range(len(s))
    for o in range(g, len(s))
    if "i" not in s[g:o+1]
]

或者在一条线上:

subs = [s[g:o+1] for g in range(len(s)) for o in range(g, len(s)) if "i" not in s[g:o+1]]

这确实会产生与循环相同的输出:

>>> s = "lallalaiial"
>>> subs = []
>>> for g in range(len(s)):
...     for o in range(g, len(s)):
...         substring = s[g:o+1]
...         passable = True
...         for v in range(len(substring)):
...             if(substring[v] == "i"):
...                 passable = False
...         if(passable):
...             subs.append(substring)
...
>>> subs
['l', 'la', 'lal', 'lall', 'lalla', 'lallal', 'lallala', 'a', 'al', 'all', 'alla', 'allal', 'allala', 'l', 'll', 'lla', 'llal', 'llala', 'l', 'la', 'lal', 'lala', 'a', 'al', 'ala', 'l', 'la', 'a', 'a', 'al', 'l']
>>> [s[g:o+1] for g in range(len(s)) for o in range(g, len(s)) if "i" not in s[g:o+1]]
['l', 'la', 'lal', 'lall', 'lalla', 'lallal', 'lallala', 'a', 'al', 'all', 'alla', 'allal', 'allala', 'l', 'll', 'lla', 'llal', 'llala', 'l', 'la', 'lal', 'lala', 'a', 'al', 'ala', 'l', 'la', 'a', 'a', 'al', 'l']

如果必须使用for循环来测试是否存在"i",那么仍然可以使用一个带有生成器表达式和^{}^{}函数的循环。当您遇到一个测试不适用于一个序列中所有元素的证据时,这些基本上与您的循环在循环中设置布尔值的操作相同,只是循环截断了该点(就像您在if char == "i":块中使用了break

if not any(char == "i" for char in s[g:o+1]):
    subs.append(s[g:o+1])

这是一个使用循环的缓慢的"i" not in s[g:o+1]实现,然后完整的列表理解变成

subs = [
    s[g:o+1]
    for g in range(len(s))
    for o in range(g, len(s))
    if not any(char == "i" for char in s[g:o+1])
]

相关问题 更多 >