我如何使else在列表理解的嵌套语句中不返回任何内容

时间:2019-01-09 08:53:04

标签: python-2.7 list-comprehension

我希望列表理解中的else语句不返回任何内容-即我只希望代码中2个if语句的输出。我该怎么办?

数据:

pleasant_sounding = ['Farm', 'Park', 'Hill', 'Green']

royal_sounding = ['Royal', 'Queen', 'King']

location_dict['Outer London'] = ['Brent Park',  'Woodford', 'Dollis Hill', 'Park Royal',  'Redbridge']

我的代码:

    [ '{} sounds pleasant'.format(name) 
if any(x in name for x in pleasant_sounding)
else '{} sounds grand'.format(name) 
if any(y in name for y in royal_sounding)
else '' for name in location_dict['Outer London'] ]

我的输出:

布伦特公园听起来不错

''

Dollis Hill听起来很愉快

Park Royal听起来很美

''

预期输出:

布伦特公园听起来不错

Dollis Hill听起来很愉快

Park Royal听起来很美

2 个答案:

答案 0 :(得分:1)

您的列表理解返回

['Brent Park sounds pleasant', '', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant', '']

您只需对其进行过滤:

>>> [t for t in <your list comprehension here> if t != '' ]
['Brent Park sounds pleasant', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant']

也就是说:

>>> [t for t in ('{} sounds pleasant'.format(name)
... if any(x in name for x in pleasant_sounding)
... else '{} sounds grand'.format(name)
... if any(y in name for y in royal_sounding)
... else '' for name in location_dict['Outer London']) if t != '' ]
['Brent Park sounds pleasant', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant']

我在内部使用了一个生成器(请注意括号),因为我们不需要构造列表,而只是一个一个地求值。 该代码仍然不清楚,因为在列表理解的中间,您有一个复杂的表达式来创建要返回的字符串。您应该使用一个函数:

>>> def text(name):
...     if any(x in name for x in pleasant_sounding):
...         return '{} sounds pleasant'.format(name)
...     elif any(y in name for y in royal_sounding):
...         return '{} sounds grand'.format(name)
...     return None # None is better than '' here
... 
>>> [t for t in (text(name) for name in location_dict['Outer London']) if t is not None ]
['Brent Park sounds pleasant', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant']

如果需要,可以使用更具功能性的样式:

>>> list(filter(None, map(text, location_dict['Outer London'])))
['Brent Park sounds pleasant', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant']

在您的if any(name ...)测试中,我仍然看到一些冗余。想象一下,您有很多听起来很不错的类型:您的代码将变得乏味。您可以使用更通用的方法:

>>> soundings = [("pleasant", ['Farm', 'Park', 'Hill', 'Green']), ("grand", ['Royal', 'Queen', 'King'])}
>>> def text(name):
...     for sounding_type, substrings in soundings:
...         if any(x in name for x in substrings):
...             return '{} sounds {}'.format(name, sounding_type)
...     return None
... 
>>> [t for t in (text(name) for name in location_dict['Outer London']) if t is not None]
['Brent Park sounds pleasant', 'Dollis Hill sounds pleasant', 'Park Royal sounds pleasant']

注意:这是Python 3.7,但是您可以使其适应Python 2.7(iteritems而不是items)。

答案 1 :(得分:1)

您还可以在列表理解中添加if ...您的代码可以简化并在最后添加一些内容,从而满足您的需求:

['{} sounds pleasant'.format(name) if any(x in name for x in pleasant_sounding)
 else '{} sounds grand'.format(name)
 for name in location_dict['Outer London']
 if any(x in name for x in pleasant_sounding+royal_sounding)]

换句话说,只是三元表达式,其理解包括过滤条件

[<X> if <condition> else <Y>
 for <var> in <container>
 if <test>]