Как заставить иначе ничего не возвращать во вложенном утверждении в понимании списка - PullRequest
0 голосов
/ 09 января 2019

Я хочу, чтобы оператор 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'] ]

Мой вывод:

Брент Парк звучит приятно

''

Доллис Хилл звучит приятно

Парк Роял звучит грандиозно

''

Ожидаемый результат:

Брент Парк звучит приятно

Доллис Хилл звучит приятно

Парк Роял звучит грандиозно

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Вы также можете добавить 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>]
0 голосов
/ 03 февраля 2019

Ваше понимание списка возвращается

['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).

...