Сглаживание вложенного выражения в выражении python

#python

Вопрос:

Могу ли я временно присвоить выражение псевдониму в другом выражении? Такая вещь, возможно, находится, скажем, в SQL, где выражения могут быть чрезвычайно длинными, но я не знаком с способом сделать это в Python. Меня на самом деле не волнует, должен ли я это делать, мне больше интересно, возможно ли это в синтаксисе Python.

 dict_a = {'p1c1': [0, 520],
 'p1c2': [400, 740],
 'p1c3': [600, 800],
 'p1c4': [600, 800],
 'p1c5': [660, 960],
 'p1c6': [760, 1200],
 'p2c1': [400, 900],
 'p2c2': [600, 920],
 'p2c3': [700, 1040],
 'p2c4': [700, 1040],
 'p2c5': [780, 1060],
 'p2c6': [800, 1160],
 'p3c1': [800, 1400],
 'p3c2': [1150, 1450],
 'p3c3': [1220, 1600],
 'p3c4': [1220, 1600],
 'p3c5': [1350, 1800],
 'p3c6': [1580, 2000]}
 

Оригинальное Выражение:

 dict_b = [dict_a[key][1] - dict_a[key][0] for key in dict_a.keys()]
 

Желанный:

 dict_b = [(r[1] - r[0]) with dict_a[key] as r for key in dict_a.keys()]
 

или что-то в этом роде

Комментарии:

1. Нет, но иногда вы можете использовать выражения присваивания, т. е. «оператор моржа», для достижения аналогичных целей

Ответ №1:

Для вашего конкретного случая использования вы можете использовать .values() вместо .keys() :

 dict_b = [r[1] - r[0] for r in dict_a.values()]
 

И если вам нужны и ключ, и значение, используйте .items() . И в других контекстах Python часто имеет удобные функции, которые позволяют выполнять аналогичные действия, например, enumerate() для перебора как индексов, так и значений последовательностей.

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

 for key in dict_a:
    r = dict_a[key]
    dict_b.append(r[1] - r[0])
 

Ответ №2:

Единственный способ добиться этого, о котором я знаю, — это использовать оператор walrus в Python 3.8 . Это не совсем то, что вы ищете, но похоже.

 dict_b = [r[1] - r[0] for key in dict_a.keys() if (r := dict_a.get(key))]
 

Комментарии:

1. Использование этого if предложения просто кажется неправильным для этого. И, конечно, это не сработает, если значение является ложным, хотя вы могли бы изменить его на if (r := dict_a[key]) or True , чтобы исправить это.

Ответ №3:

Тебе это и не нужно. Вы используете ключ только для получения значения, но вы можете перебирать значения напрямую.

 dict_b = [v[1] - v[0] for v in dict_a.values()]
 

Если вам действительно нужны ключи, то вы можете повторить и то, и другое в тандеме.

 dict_b = {k: v[1] - v[0] for k, v in dict_a.items()}