Возможно ли понимание этого списка в Python?
У меня есть отношения любви/ненависти со списком. С одной стороны, я думаю, что они аккуратные и элегантные. С другой стороны, я ненавижу их читать. (особенно те, которые я не писал) Я обычно придерживаюсь правила, сделайте его доступным для чтения, пока не потребуется скорость. Поэтому мой вопрос действительно академичен на данный момент.
Мне нужен список станций из таблицы, у которых часто есть дополнительные пробелы. Мне нужны эти пробелы. Иногда эти станции пусты и не должны включаться.
stations = []
for row in data:
if row.strip():
stations.append(row.strip())
Что переводится в этот список:
stations = [row.strip() for row in data if row.strip()]
Это работает достаточно хорошо, но мне кажется, что я делаю полосу дважды. Я догадался, что .strip() на самом деле не требуется дважды и, как правило, медленнее, чем просто назначать переменную.
stations = []
for row in data:
blah = row.strip()
if blah:
stations.append(blah)
Оказывается, я был прав.
> Striptwice list comp 14.5714301669
> Striptwice loop 17.9919670399
> Striponce loop 13.0950567955
Timeit показывает между двумя сегментами цикла, второй (полоса один раз) работает быстрее. Здесь нет ничего удивительного. Я удивляюсь, что понимание списка лишь незначительно медленнее, хотя оно делает полосу дважды.
Мой вопрос: Есть ли способ написать представление списка, которое только делает полосу раз?
Результаты:
Вот результаты выбора предложений
# @JonClements & @ErikAllik
> Striptonce list comp 10.7998494348
# @adhie
> Mapmethod loop 14.4501044569
Ответы
Ответ 1
Вложенные понимания могут быть сложными для чтения, поэтому мое первое предпочтение было бы следующим:
stripped = (x.strip() for x in data)
stations = [x for x in stripped if x]
Или, если вы inline stripped
, вы получаете одно (вложенное) понимание списка:
stations = [x for x in (x.strip() for x in data) if x]
Обратите внимание, что первое/внутреннее понимание является фактически генераторным выражением, которое, другими словами, является ленивым списком; это чтобы избежать повторения дважды.
Ответ 2
Существует - сначала создать генератор разделенных строк, затем используйте это:
stations = [row for row in (row.strip() for row in data) if row]
Вы также можете записать его без comp, например (swap to imap
и удалить list
для Python 2.x):
stations = list(filter(None, map(str.strip, data)))
Ответ 3
Примените полосу ко всем элементам с помощью map() и затем фильтруйте.
[item for item in map(lambda x: x.strip(), list) if item]