Рассмотрите следующий код:
>>> colprint([
(name, versions[name][0].summary or '')
for name in sorted(versions.keys())
])
То, что делает этот код, должно распечатать элементы словаря versions
в порядке возрастания keys
, но начиная с value
другой отсортированный список, только сводка его первого элемента ('макс.') печатается.
Так как я знаком с let
от шепелявости я переписал вышеупомянутое как:
>>> colprint([
(name, package.summary or '')
for name in sorted(versions.keys())
for package in [versions[name][0]]
)]
Вы думаете, что это нарушает быть Pythonic? Это может быть улучшено?
Примечание: Для любопытного, colprint
определяется здесь.
Почему бы не использовать кортежи?
colprint([(name, version[0].summary or '')
for (name, version) in sorted(versions.iteritems())])
или даже
colprint(sorted([(name, version[0].summary or '')
for (name, version) in versions.iteritems()]))
Кроме того, вы можете рассмотреть (в моем первом примере) удаление []
, потому что таким образом вы получаете генератор вместо списка (который может быть полезен или бесполезен, поскольку я предполагаю, что при этом будет напечатан весь массив, поэтому вы не сохраните никаких оценок).
Итак, вы используете «for x in [y]» вместо «let x y».
Попытка эмулировать синтаксис языка на другом языке никогда не является хорошей идеей. Я думаю, что исходная версия намного яснее.
В большинстве случаев я бы не стал использовать «хитрое предложение for» (или «let-эквивалент»), но я бы использовал, если это естественный способ избежать повторения, особенно дорогостоящего повторения. Например,
xs = [(y, y*1.2, y-3.4) for z in zs for y in [somefun(z)] ]
мне кажется намного лучше, чем три раза вызывать somefun
! -) Так что об этом стоит помнить, даже если, вероятно, не стоит использовать там, где он не удаляет повторение.
Вы можете переместить сортировку в конец, чтобы избежать некоторых промежуточных списков.
Это выглядит немного лучше, я думаю:
colprint(sorted(
(name, version[0].summary or '')
for (name,version) in versions.iteritems())
))
Python3 может работать даже лучше:
colprint(sorted(
(name, first_version.summary or '')
for (name,(first_version,*_)) in versions.items())
))
Как говорит Тордек, вы можете использовать items()
или iteritems()
в этом случае, чтобы избежать проблемы:
colprint(sorted((name, packages[0].summary or '')
for (name, packages) in versions.items()))
Перемещение сортировки наружу - это приятный штрих.
[Обратите внимание, что использование items()
слегка изменило порядок сортировки - раньше он был по имени с привязками, разрешенными по исходному порядку (сорт Python стабилен), теперь он по имени с привязками, разрешенными по сводке. Так как исходный порядок диктата случайен, новое поведение, вероятно, лучше.]
Но для других целей (например, для примера Алекса Мартелли), "let"-alike все же может быть полезен.
Я также однажды обнаружил трюк для var в [value]
, но теперь нахожу его уродливым.
Более чистой альтернативой может быть "конвейер" понятий/генераторов, использующий трюк "декорировать/недекорировать", чтобы передать добавленную стоимость в кортеж:
# You could write this with keys() or items() -
# I'm just trying to examplify the pipeline technique.
names_packages = ((name, versions[name][0])
for name in versions.keys())
names_summaries = ((name, package.summary or '')
for (name, package) in names_packages)
colprint(sorted(names_summaries))
Или примененный к примеру Алекса:
ys = (somefun(z) for z in zs)
xs = [(y, y*1.2, y-3.4) for y in ys]
(в котором вам даже не нужны оригинальные значения z
, чтобы промежуточные значения не были кортежами)
Смотрите http://www.dabeaz.com/generators/ для более мощных примеров "конвейерной" техники....