努力理解这一点';高级';python中的for循环
我知道如何做基本for循环,但我很难理解这段代码中的for循环。我正在寻找一种在列表中查找子字符串并获取索引的方法(因此我可以获取该字符串并对其进行切片-在本例中,如果有一个列表项X分钟,则提取值25) 这段代码可以工作并返回3,但我很难理解I for I等-我只处理过以for开头的for循环。注意我没有定义i或s。我确实理解列举 请注意,可能还有其他方法可以做到这一点,但当我开始走这条路时,我意识到我不理解我发现的许多类似于下面for循环的示例,因此我现在专注于理解这种方法 非常感谢事先的解释努力理解这一点';高级';python中的for循环,python,for-loop,Python,For Loop,我知道如何做基本for循环,但我很难理解这段代码中的for循环。我正在寻找一种在列表中查找子字符串并获取索引的方法(因此我可以获取该字符串并对其进行切片-在本例中,如果有一个列表项X分钟,则提取值25) 这段代码可以工作并返回3,但我很难理解I for I等-我只处理过以for开头的for循环。注意我没有定义i或s。我确实理解列举 请注意,可能还有其他方法可以做到这一点,但当我开始走这条路时,我意识到我不理解我发现的许多类似于下面for循环的示例,因此我现在专注于理解这种方法 非常感谢事先的解释
uptime list = ['routerX uptime is 2 weeks', '6 days', '4 hours', '25 minutes']
min_index = [i for i, s in enumerate(uptime_list) if 'minute' in s]
函数
enumerate()
将以[(0,element1),(1,element2),…]
的形式返回元组列表,并使用条件列表理解来过滤该列表,最后只选择索引 这里的第一个术语,i
,是循环每次迭代都会返回的内容(假设条件为真,稍后将详细介绍)
在第二部分中,enumerate(正常运行时间列表)中的i,s的函数将把字符串列表变成一个元组列表,可以像下面这样迭代:
>>> for x in enumerate(uptime_list): print(x)
(0, 'routerX uptime is 2 weeks')
(1, '6 days')
(2, '4 hours')
(3, '25 minutes')
然后,循环中的每个迭代都会发生多个赋值。例如,如果执行x,y=0,1
,则x
将为0,y
将为1。唯一的区别是,在这种情况下,元组来自enumerate
函数,并被分配到i
和s
最后,最后一部分,如果s
中的'minute'将仅在条件为真时(即当前正在查看的s
变量中的'minutes'时)返回第一个i
。如果向包含字符串“分钟”的uptime\u列表添加第二个术语,则min\u index
将包含多个数字,因为该条件将适用于列表中的多个元素。对于语句,列表理解可以直接转换为显式
从第一个for
子句中提取所有内容,并将它们嵌套为单独的语句。在最里面的语句中,将for
子句前面的表达式追加到列表中。这就是全部规则。那么这个,
min_index = [i for i, s in enumerate(uptime_list) if 'minute' in s]
……是指:
min_index = []
for i, s in enumerate(uptime_list):
if 'minute' in s:
min_index.append(i)
有关详细说明,请参见官方教程中的。有关语法和语义的详细信息,请参见语言参考中的*
如果您不理解,这只是获取列表(或其他iterable)中每个元素的索引和值的一种方法<例如,枚举(['x','y','z'])
给你(0,'x')
,然后(1,'y')
,然后(2,'z')
因此,每次通过循环,s
都是uptime_list
中的一个值,i
是该值的索引。因此,在最后,我们有一个来自uptime\u list
的所有索引的列表,其对应的值包括字符串'minute'
。例如,鉴于此:
uptime_list = ['20 seconds', '3 minutes 5 seconds', '17 seconds', '1 minute']
您将得到[1,3]
,因为元素#1和#3包含分钟
*请注意,一些详细信息随着时间的推移而发生了变化,因此如果您使用的是较旧的版本,尤其是2.x版本,请在文档中切换到正确的版本。这是一个列表理解的示例。它基本上有三个部分:第一个i
,枚举中i,s的(正常运行时间列表)
,以及s中的if'minute'。第一部分是一种映射,第二部分定义域,第三部分是筛选操作。可能是重复的哦,这只是另一种编写map(lambda l:l[0]、filter(lambda l:'minute'in l[1]、zip(range(len(uptime_list))、uptime_list))
fun,(我认为这就是为什么他们在Python中使用列表理解,并且不推荐使用map
和filter
)。@TessellatingHeckler:嗯,表达式I
显然比函数lambda(I,s):I
更详细。就我个人而言,除非我有一个命名函数,否则我从不使用map
(或绑定或未绑定的方法,或我出于其他原因创建的部分,等等),但我认为在某种程度上,这只是一个品味问题;我认为比我更了解“Pythonic”的一些人比我更经常地使用它。@tessellingheckler:至于“mapzip”,我真的不知道它的名字(这就是为什么我使用了笨拙的术语“多参数map
)。有几次我写了map(f,zip(…)
,然后意识到我不需要2.x(而不是3.x)中的zip
)您可以将它用作非惰性的无填充值izip_longest
。但我所看到的最常见的用法实际上并没有那么引人注目:作为使用partial
或lambda
绑定参数的替代,如映射(pow,a,repeat(2))
itertools
文档中的示例,只有当你在脑海中翻译Haskell时,这才是你的第一个想法。干杯-追加从何而来?当你将其分解为多行时,枚举非常清楚-但初始i在哪里?(如“i代表i”)编辑只是阅读,有意义,thanks@wintermute000:为了帮助改进答案:我写了“你在for
子句之前附加表达式”。在这种情况下,这是第一个I
。我如何才能更清楚地说明这一点?