стиль стиля шепелявости 'позволил' синтаксису в пониманиях списка Python

Рассмотрите следующий код:

>>> 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 определяется здесь.

6
задан Community 23 May 2017 в 12:01
поделиться

5 ответов

Почему бы не использовать кортежи?

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()]))

Кроме того, вы можете рассмотреть (в моем первом примере) удаление [], потому что таким образом вы получаете генератор вместо списка (который может быть полезен или бесполезен, поскольку я предполагаю, что при этом будет напечатан весь массив, поэтому вы не сохраните никаких оценок).

7
ответ дан 8 December 2019 в 13:46
поделиться

Итак, вы используете «for x in [y]» вместо «let x y».

Попытка эмулировать синтаксис языка на другом языке никогда не является хорошей идеей. Я думаю, что исходная версия намного яснее.

4
ответ дан 8 December 2019 в 13:46
поделиться

В большинстве случаев я бы не стал использовать «хитрое предложение for» (или «let-эквивалент»), но я бы использовал, если это естественный способ избежать повторения, особенно дорогостоящего повторения. Например,

xs = [(y, y*1.2, y-3.4) for z in zs for y in [somefun(z)] ]

мне кажется намного лучше, чем три раза вызывать somefun ! -) Так что об этом стоит помнить, даже если, вероятно, не стоит использовать там, где он не удаляет повторение.

5
ответ дан 8 December 2019 в 13:46
поделиться

Вы можете переместить сортировку в конец, чтобы избежать некоторых промежуточных списков.

Это выглядит немного лучше, я думаю:

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())
    ))
0
ответ дан 8 December 2019 в 13:46
поделиться

Как говорит Тордек, вы можете использовать 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/ для более мощных примеров "конвейерной" техники....

1
ответ дан 8 December 2019 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: