我可以进行列表理解,以便在for循环后附加一个值

时间:2018-10-08 08:14:13

标签: python python-3.x list-comprehension

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循环-即使没有它也可以实现相同的结果。

3 个答案:

答案 0 :(得分:3)

列表理解是关于在for循环中追加到列表(在开始时创建列表,然后返回该列表),但是您需要先稍微转换一下逻辑。

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

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

至少具有一个循环,具有零个或多个if过滤器和附加循环。如果可以将代码转换为这种结构,则可以使其成为列表理解。

您的代码还不存在,因为您已经拥有

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

但可以轻松地转换为简单的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",那么您仍然可以使用带有生成器表达式和all()的表达式或any()函数。当您遇到证据证明一个测试不能满足序列中的所有元素时,这些本质上与在循环中设置布尔值的功能相同,只是循环被缩短到该点(就像您使用了breakif char == "i":块中:

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

答案 1 :(得分:0)

由于您仅使用ggplot标志来测试p <- ggplot() + #Pitch geom_rect(aes(xmin = 100, xmax = 101, ymin = 44.7, ymax = 55.1), fill = NA, colour = "black", size = 1) + # Goal geom_rect(aes(xmin = 50, xmax = 100, ymin = 0, ymax = 100), fill = NA, colour = "black", size = 1) + # Field Around geom_rect(aes(xmin = 83, xmax = 100, ymin = 21, ymax = 79), fill = NA, colour = "black", size = 1) + #18yrd box geom_rect(aes(xmin = 100, xmax = 94, ymin = 36.8, ymax = 63.2), fill = NA, colour = "black", size = 1) + #6yrd box geom_point(aes(x = 88.5, y = 50), colour = "black", size = 1.5) + #PK spot geom_point(aes(x = 50, y = 50), colour = "black", size = 2) + #Centre circle dot geom_point(aes(x = 50, y = 50), colour = "black", size = 55, shape = 1) + #centre circle geom_rect(aes(xmin=49, xmax=50,ymin=0,ymax=100),fill='white',color='white',size=1)+ coord_flip() + xlim(50, 101) + ylim(0,100)+ #Theme theme( panel.background = element_rect(fill = "transparent",colour = NA), plot.margin = unit(c(0,0,0,0), "cm"), plot.title = element_text(size = 14, hjust = 0.5, vjust = 1.25), plot.background = element_rect(fill = "transparent", colour = NA), line = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text = element_blank(), legend.position = "none", legend.box = "vertical", legend.background = element_rect(fill = "transparent") ) p 是否在当前子字符串中,因此可以使用以下列表推导,条件是使用passable运算符:

i

这和您的代码都将输出:

in

答案 2 :(得分:0)

由于要保留最内层的循环,因此可以执行以下操作:

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