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

时间:2015-05-01 02:34:57

标签: 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')]

也不起作用。我知道通过***解压缩,但我不确定这里适合的地方。是否有可能将这些类型的循环变成理解,希望以一种整洁的方式?

2 个答案:

答案 0 :(得分:9)

您无法直接将该循环翻译为理解。作为表达式的理解只能包含表达式,而赋值是语句。

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

首先,以两次调用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循环没有错,如果中间临时变量使代码更清晰,那么没有比使用赋值语句更好的方法。

答案 1 :(得分:6)

要有创意。

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

...

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