Подтвердить что ты не робот

В Python лучше использовать списки или для каждого цикла?

Какое из следующего лучше использовать и почему?

Способ 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)

4b9b3361

Ответ 1

Если итерация выполняется для ее побочного эффекта (как в примере с "печатью" ), тогда цикл становится яснее.

Если итерация выполняется, чтобы построить составное значение, тогда понимание списка обычно более читаемо.

Ответ 2

Конкретные примеры кода, которые вы выбрали, не демонстрируют преимущества понимания списка, поскольку он (неправильно) используется для тривиальной задачи печати. В этом простом случае я бы выбрал простой цикл for.

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

Пример, который ясно показал бы превосходство списка comp, можно было бы сделать, заменив пример print на один, связанный с созданием другого фактического списка, добавив один на каждую итерацию цикла for:

L = []
for x in range(10):
    L.append(x**2)

Дает те же L как:

L = [x**2 for x in range(10)]

Ответ 3

Я считаю, что первый пример лучше - менее подробный, понятный и понятный.

На мой взгляд, пойдите с тем, что наилучшим образом использует ваше намерение, в конце концов:

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

- от "Структура и интерпретация компьютерных программ" Абельсона и Суссмана

Кстати, поскольку вы только начинаете изучать Python, сразу изучите новый синтаксис форматирования строк:

for k, v in os.environ.items():
    print "{0}={1}".format(k, v)

Ответ 4

Понимание списка более чем в два раза быстрее, чем явный цикл. Основываясь на вариации Бен Джеймса, но заменим 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, вам необходимо осваивать список.

Ответ 5

Первый, на мой взгляд, потому что:

  • Он не создает огромную строку.
  • Он не создает огромный список (его можно легко установить с помощью генератора, удалив []).

В обоих случаях вы получаете доступ к элементам одинаковым образом (с помощью словарного итератора).

Ответ 6

Предполагается, что представления списков должны выполняться на уровне C, поэтому, если существует огромный цикл, понимание списка является хорошим выбором.

Ответ 7

Я согласен с @Ben, @Tim, @Steven:

  • читаемость является самой важной вещью ( "импортируйте это", чтобы напомнить себе, что есть)
  • listcomp может быть или не быть намного быстрее, чем версия с итерационным контуром... это зависит от общего количества вызовов функций, которые выполняются
  • Если вы решите пойти с listcomps с большими наборами данных, лучше использовать выражения генераторов вместо

Пример:

print "\n".join("%s=%s" % (k, v) for k,v in os.environ.iteritems())

в фрагменте кода выше, я сделал два изменения... Я заменил listcomp на genexp, и я изменил вызов метода на iteritems(). [эта тенденция движется вперед, как в Python 3, iteritems() заменяется и переименовывается в items().]