Ответ 1
Если итерация выполняется для ее побочного эффекта (как в примере с "печатью" ), тогда цикл становится яснее.
Если итерация выполняется, чтобы построить составное значение, тогда понимание списка обычно более читаемо.
Какое из следующего лучше использовать и почему?
Способ 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? Я предполагаю, что нет разницы в производительности, но я могу ошибаться. Каковы были бы преимущества и недостатки этих двух методов?
(Код, взятый из Погружение в Python)
Если итерация выполняется для ее побочного эффекта (как в примере с "печатью" ), тогда цикл становится яснее.
Если итерация выполняется, чтобы построить составное значение, тогда понимание списка обычно более читаемо.
Конкретные примеры кода, которые вы выбрали, не демонстрируют преимущества понимания списка, поскольку он (неправильно) используется для тривиальной задачи печати. В этом простом случае я бы выбрал простой цикл for
.
Во многих других случаях вам нужно будет предоставить фактический список другой функции или методу, а понимание списка - самый простой и удобный способ сделать это.
Пример, который ясно показал бы превосходство списка 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, понимание списка - это странная вещь, которую мне трудно понять!: -O Но как только я получил к нему пользу, он становится очень красивой короткой нотной записью. Если вы станете профессионалом в Python, вам необходимо осваивать список.
Первый, на мой взгляд, потому что:
[]
).В обоих случаях вы получаете доступ к элементам одинаковым образом (с помощью словарного итератора).
Предполагается, что представления списков должны выполняться на уровне C, поэтому, если существует огромный цикл, понимание списка является хорошим выбором.
Я согласен с @Ben, @Tim, @Steven:
Пример:
print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())
в фрагменте кода выше, я сделал два изменения... Я заменил listcomp на genexp, и я изменил вызов метода на iteritems()
. [эта тенденция движется вперед, как в Python 3, iteritems()
заменяется и переименовывается в items()
.]