Проблема в понимании списков Python - PullRequest
7 голосов
/ 01 февраля 2009

Что означает последняя строка в следующем коде?

import pickle, urllib                                                                                                                                                     

  handle = urllib.urlopen("http://www.pythonchallenge.com/pc/def/banner.p")
  data = pickle.load(handle)
  handle.close()

  for elt in data:
         print "".join([e[1] * e[0] for e in elt])

Моя попытка решить проблему:

  • "". Join ... использует метод объединения для очистки текста
  • e [1] * e [0] умножает два последующих значения в последовательности, e
  • Я не уверен, что е
  • Я не уверен, что это значит, когда у вас есть что-то до -loop, например: e[1] * e[0] for e in elt

Ответы [ 6 ]

20 голосов
/ 01 февраля 2009

Возможно, лучше всего объяснить на примере:

print "".join([e[1] * e[0] for e in elt])

является краткой формой

x = []
for e in elt:
  x.append(e[1] * e[0])
print "".join(x)

Понимания списка - просто синтаксический сахар для циклов for, которые делают выражение из последовательности операторов.

elt может быть произвольным объектом, так как вы загружаете его из солений, и e также. Использование предполагает, что это тип sequence , но это может быть что угодно, что реализует протокол последовательности.

7 голосов
/ 01 февраля 2009

Во-первых, вам нужно поместить http: // перед URL, то есть:

handle = urllib.urlopen("http://www.pythonchallenge.com/pc/def/banner.p")

Выражение [e for e in a_list] - это понимание списка , которое генерирует список значений.

Для строк Python оператор * используется для повторения строки. Попробуйте ввести команды одну за другой в интерпретатор, а затем посмотрите на данные:

>>> data[0]
[(' ', 95)]

Это показывает, что каждая строка данных является кортежем, содержащим два элемента.

Таким образом, выражение e[1] * e[0] фактически является строкой в ​​e[0], повторенной e[1] раз.

Следовательно, программа рисует баннер.

4 голосов
/ 01 февраля 2009

[e[1] * e[0] for e in elt] - это понимание списка, которое оценивает сам список, просматривая другой список, в данном случае elt. Каждый элемент в новом списке - e[1]*e[0], где e - соответствующий элемент в elt.

2 голосов
/ 04 февраля 2009

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

print "".join([e[1] * e[0] for e in elt])

может, например, стать

print "".join([e[1] * e[0] for e in elt if len(e) == 2])

для работы только с предметами в elt, которые имеют два элемента.

1 голос
/ 01 февраля 2009

Энди отличный ответ!

Если вы хотите увидеть каждый шаг цикла (с переносами строк), попробуйте это:

for elt in data:
    for e in elt:
        print "e[0] == %s, e[1] == %d, which gives us:  '%s'" % (e[0], e[1], ''.join(e[1] * e[0]))
1 голос
/ 01 февраля 2009

join () - это строковый метод, который работает с разделителем в новой строке

>>> ':'.join(['ab', 'cd'])
>>> 'ab:cd'

и понимание списка там не нужно, генератора будет достаточно

...