Питон петли против понимания списки против карты для побочных эффектов (т. е. не используя возвращаемое значение )
TL; DR какой из них самый лучший?
1.- [r.update(r.pop('some_key')) for r in res if r.get('some_key')]
2.- map(lambda r: r.update(r.pop('some_key') if r.get('some_key') else []), res)
3.- map(lambda r: r.update(r.pop('some_key')), filter(lambda r: r.get('some_key'), res))
4.- for r in res:
if r.get('some_key'):
for element in r['some_key']:
r[element] = r['some_key'][element]
del r['some_key']
5.- Insert your own approach here
Примечание : это не производственный код. Это код, который выполняется в тестовом наборе, поэтому я больше беспокоюсь о удобочитаемости/ремонтопригодности, чем о производительности. Тем не менее, я также хотел бы знать, изменится ли решение относительно того, что лучше (учет компромисса производительности/удобочитаемости), если это будет производственный код. Число элементов "some_key" довольно мало, если это имеет значение.
Контекст : у меня есть прочитайте Python List Comprehension Vs. Map , где принятый ответ гласит:
[...] Список постижений может быть быстрее в других случаях и большинство (не все) питонистов считают их более прямыми и ясными [...].
Тем не менее, общепринятый ответ на является ли Питоническим использовать понимание списка только для побочных эффектов? говорит:
PS: у меня уже есть мнение, какое из них лучше, но один мой коллега не согласен. Вот почему я спрашиваю.Это очень антипифонически, чтобы сделать это [использовать списки понимания только для побочных эффектов, игнорирование возвращаемого значения], и любой опытный питонист устроит вам ад за это. Промежуточный список отбрасывается после его создания, и он потенциально может быть очень, очень большим, и поэтому дорогим для создания.
2 ответа:
1.- [r.update(r.pop('some_key')) for r in res if r.get('some_key')]
Список понимания для побочного эффекта не рекомендуется. Он создает список, который отбрасывается в конце операции
2.- map(lambda r: r.update(r.pop('some_key') if r.get('some_key') else []), res)
Не сильно отличается от
1
, за исключением того, что это сломается в Py 3.X.3.- map(lambda r: r.update(r.pop('some_key')), filter(lambda r: r.get('some_key'), res))
Хуже, чем
3
. Помимо использованияmap
и полагаясь на побочный эффект, вы добавляете накладные расходы вызова функции4.- for r in res: if r.get('some_key'): for element in r['some_key']: r[element] = r['some_key'][element] del r['some_key']
Это лучше, чем все остальное
[8]}5.- Вставьте сюда свой собственный подход
- не генерируется ненужный список, который будет отброшен
- будет работать в Py 3.x
- нет явных накладных расходов на вызов функции
for r in res: if 'some_key' in r: r.update(r['some_key']) del r['some_key']