假设我们必须在一次迭代中在一个列表理解中插入两个元素,但是我们必须选择插入哪两个元素。我们如何才能做出这样的清单理解。在
为示例:-
假设我们有一个列表hostnames = ['aa', 'bb', 'dd', 'pp', 'bb', 'zz', 'hh']
。在
现在我们要修改这个列表,使以p开头的主机名应该有一个名为“_prd”(例如“pp_prd”)的额外元素,对于以h开头、值为“_uat”的主机名也应该有一个额外的元素(例如“hh_uat”)。在
所以上面列表的期望输出是mod_hostnames = ['aa', 'bb', 'dd', 'pp_prd', 'pp', 'bb', 'zz', 'hh_uat','hh']
。在
现在我想这样写-
>>> fh=lambda x: x+'_uat'
>>> fp=lambda x:x+'_prd'
>>> fo=lambda x:x
>>> lis
['aa', 'bb', 'dd', 'pp', 'bb', 'zz', 'hh']
>>> hostnames = lis
>>> mod_hostnames = [f(host) for f in (fo,fp) if host[0]=='p' else f(host) for f in (fo,fh) if host[0]=='h' else host for host in hostnames]
File "<stdin>", line 1
mod_hostnames = [f(host) for f in (fo,fp) if host[0]=='p' else f(host) for f in (fo,fh) if host[0]=='h' else host for host in hostnames]
^
SyntaxError: invalid syntax
我们得到一个语法错误。我还知道在列表理解中,第二个循环运行得更快(就像for循环一样),而在我们的代码中,host in hostnames
运行得更快,而不是另一种所需的方式。所以我试了一下:
有什么建议吗?或者这在列表理解中是不可能的。
我知道这根本不可读,有更好的方法来写出来。(例如使用dict“switch”在for循环中的一个语句中写入此语句,或者在循环中使用旧的if-else语句,等等)。在
后解决方案编辑:收到了精彩的答复。谢谢!有人能解释一下为什么我发布的代码也是错误的吗?
我觉得这是因为当condition为true或false时计算的语句只会解析为一个空的for循环:for f in (fo,fp) if host[0]=='p' else for f in (fo,fh)
如果host[0]=='p',程序将进入一个空的for循环for f in (fo,fp)
。这是对的吗?
我想,把我错误的理解力逆向工程到for循环中,我想可以澄清这一点。在
首先,您需要编写一个始终返回元组的转换函数,必要时使用单元组:
然后你可以这样做:
^{pr2}$itertools.chain.from_iterable
本质上是一个连接所有中间元组的平坦操作,外部的list
将该生成器的输出转换为实际的列表。在然而,在这种情况下,使用传统的
for
循环的更普通的方法更有意义。在你的想法还可以,但是你的语法不正确。以下是修改现有代码的方法:
将
if
/else
括起来,用括号修改f
的iterable,并且还需要(fo,)
中的尾随逗号使其成为元组。在也可以使用
str.startswith
,而不是为字符串中的第一个字符编制索引。在在任何情况下,传统的循环在这里是完美的,并且为了可读性/易于理解,可能更可取:
^{pr2}$实际上,最好从传统的
for
循环开始,这样您就可以大致了解困难所在:要创建一个理解列表,您需要转换
if
。。。elif
。。。else
语句在一行语句中使用。。。if
。。。else
。。。在您可以按如下方式处理:
^{pr2}$嗯,这有点棘手。在
要将这个循环转换为一个理解列表,您需要迭代
^{3}$r
值。你会在理解列表中得到一个理解列表。在哼!我觉得写一份理解清单太复杂了。谁会想调试它呢?在
对于可维护性,我建议使用一个小功能的解决方案:
在这里!在
相关问题 更多 >
编程相关推荐