Какое из следующего лучше для использования и почему?
Метод 1:
for k, v in os.environ.items():
print "%s=%s" % (k, v)
Метод 2:
print "\n".join(["%s=%s" % (k, v)
for k,v in os.environ.items()])
Я склонен приводить к первому как более понятное, но это могло бы просто быть то, потому что я плохо знаком с пониманиями Python и списка, являются все еще несколько внешними мне. Второй путь считают большим количеством Pythonic? Я предполагаю, что нет никакого различия в производительности, но я могу быть неправым. Каковы были бы преимущества и недостатки этих 2 методов?
(Код, взятый от Погружения в Python)
Если итерация выполняется из-за ее побочного эффекта (как в вашем примере «печати»), то цикл будет более понятным.
Если итерация выполняется для построения составного значения, то понимание списков обычно более читабельно.
Обработка списков должна выполняться на уровне C, поэтому при большом цикле понимание списков - хороший выбор.
Конкретные примеры кода, которые вы выбрали, не демонстрируют никаких преимуществ понимания списка, потому что он (неправильно) используется для тривиальной задачи печати. В этом простом случае я бы выбрал простой цикл for
.
Во многих других случаях вы захотите передать фактический список другой функции или методу, и понимание списка - самый простой и читабельный способ сделать это.
Пример, который наглядно продемонстрирует превосходство list comp, можно сделать, заменив пример print
на пример с созданием еще одного фактического списка путем добавления к одному на каждой итерации цикла for
:
L = []
for x in range(10):
L.append(x**2)
Дает тот же L
, что и:
L = [x**2 for x in range(10)]
Я считаю, что первый пример лучше - менее подробный, более ясный и более читаемый.
На мой взгляд, в конце концов, следуйте тому, что лучше всего передает ваше намерение:
Программы должны быть написаны для людей читать, и только кстати для машины для исполнения.
- из «Структура и интерпретация компьютерных программ» Абельсона и Сассмана
Между прочим, поскольку вы только начинаете изучать Python, сразу же начните изучать новый синтаксис форматирования строк :
for k, v in os.environ.items():
print "{0}={1}".format(k, v)
Понимание списка более чем в два раза быстрее, чем явный цикл. Если взять за основу вариацию Бена Джеймса, но заменить x**2 на более тривиальную функцию x+2, то получатся две альтернативы:
def foo(n):
L = []
for x in xrange(n):
L.append(x+2)
return L
def bar(n):
return [x+2 for x in xrange(n)]
Результат подсчета времени:
In [674]: timeit foo(1000)
10000 loops, best of 3: 195 us per loop
In [675]: timeit bar(1000)
10000 loops, best of 3: 81.7 us per loop
С большим отрывом выигрывает понимание списка.
Я согласен с тем, что читабельность должна быть приоритетнее оптимизации производительности. Однако читабельность находится в поле зрения зрителя. Когда я только начинал изучать Python, понимание списков было странной вещью, которую мне было трудно понять! Но как только я привык к нему, он стал действительно удобной короткой ручной нотацией. Если вы хотите стать знатоком Python, вы должны овладеть пониманием списков.
Я согласен с @Ben, @Tim, @Steven:
Пример:
print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())
в приведенном выше фрагменте кода я внес два изменения ... Я заменил listcomp на genexp и изменил вызов метода iteritems ()
. [эта тенденция развивается, как и в Python 3, iteritems ()
заменяет и переименовывается в items ()
.]
На мой взгляд, первый, потому что:
[]
). В обоих случаях вы получаете доступ к элементам одинаково (используя итератор словаря).