我希望列表理解中的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听起来很美
答案 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>]