小编典典

将带有赋值的循环转换为理解力

python

将循环转换为理解很简单:

mylist = []
for word in ['Hello', 'world']:
    mylist.append(word.split('l')[0])

mylist = [word.split('l')[0] for word in ['Hello', 'world']]

但是,我不确定在循环涉及为引用分配值时如何进行。

mylist = []
for word in ['Hello', 'world']:
    split_word = word.split('l')
    mylist.append(split_word[0]+split_word[1])

并且理解最终看起来像这样:

mylist = [word.split('l')[0]+word.split('l')[1] for word in ['Hello', 'world']]

这将计算word.split('l')多次,而循环仅计算一次并保存一个引用。我尝试了以下方法:

mylist = [split_word[0]+split_word[1] for word in ['Hello', 'world'] with word.split('l') as split_word]

失败的原因with是无法正常工作,并且:

mylist = [split_word[0]+split_word[1] for word in ['Hello', 'world'] for split_word = word.split('l')]

这也不起作用。我知道可以通过*和打开包装,**但不确定在哪里放置。是否有可能以一种整洁的方式将这种循环变成理解?


阅读 161

收藏
2020-12-20

共1个答案

小编典典

您不能直接将该循环转换为理解力。理解是表达式,只能包含表达式,赋值是语句。

但是,这并不意味着没有选择。

首先,split您只需拨打两次电话即可:

mylist = [word.split('l')[0]+word.split('l')[1] for word in ['Hello', 'world']]

但是您不想打split两次电话。


解决该问题的最通用方法是使用一连串生成器表达式(末尾具有一个列表理解)来转换事物:

words = (word.split('l') for word in ['Hello', 'world'])
mylist = [w[0]+w[1] for w in words]

如果您真的想将所有内容合并为一个表达式,则可以:

mylist = [w[0]+w[1] for w in 
          (word.split('l') for word in ['Hello', 'world'])]

但是除非您实际上 需要 将其包含在表达式中,否则不这样做可能更易读。


在这种情况下,一种更具体的方式是w[0]+w[1]用不需要w两次引用的等效项替换:

mylist = [''.join(word.split('l')[:2]) for word in ['Hello', 'world']]

您也可以一概而论。您可以将 任何
表达式转换为函数,这意味着可以通过将表达式作为参数传递给该函数来避免对表达式的任何部分求值。如果没有一个函数可以满足您的要求,请编写该函数:

def join_up(split_word):
    return split_word[0]+split_word[1]
mylist = [join_up(word.split('l')) for word in ['Hello', 'world']]

如果您需要在不重复任何工作的情况下将所有内容整合到一个表达式中,则可能会很麻烦:

mylist = [(lambda split_word: split_word[0]+split_word[1])(word.split('l')) 
          for word in ['Hello', 'world']]

但是最终,除非我已经有了一个可以满足我需要的函数,否则我将使用发电机链表达式解决方案。

或者,当然,只需将其保持在明确的循环中即可;for循环没有什么问题,而且如果中间临时变量使您的代码更清晰,那么没有比使用赋值语句更好的方法了。

2020-12-20