Проблема в понимании понимания списков Python
Что означает последняя строка в следующем коде?
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... использует join -method для пустого текста
- e [1] * e [0] умножает два последующих значения в последовательности, e
- Я не уверен, что такое e
- Я не уверен, что это значит, когда у вас есть что-то раньше для -loop, например:
e[1] * e[0] for e in elt
Ответы
Ответ 1
Может быть, лучше всего объяснить с помощью примера:
print "".join([e[1] * e[0] for e in elt])
- краткая форма
x = []
for e in elt:
x.append(e[1] * e[0])
print "".join(x)
List comprehensions - это просто синтаксический сахар для циклов for
, которые вызывают выражение из последовательности инструкций.
elt
может быть произвольным объектом, так как вы загружаете его из соленья и e
аналогичным образом. Использование предполагает, что это тип sequence, но это может быть просто все, что реализует протокол последовательности.
Ответ 2
Во-первых, вам нужно поместить 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]
раз.
Следовательно программа рисует баннер.
Ответ 3
[e[1] * e[0] for e in elt]
- это понимание списка, которое оценивает сам список, перебирая другой список, в этом случае elt
. Каждый элемент в новом списке e[1]*e[0]
, где e
- соответствующий элемент в elt
.
Ответ 4
Сам вопрос уже полностью ответил, но я хотел бы добавить, что понимание списка также поддерживает фильтрацию. Исходная строка
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, которые имеют два элемента.
Ответ 5
join() - это строковый метод, который работает с разделителем в новой строке
>>> ':'.join(['ab', 'cd'])
>>> 'ab:cd'
и не должно быть понимания списка, генератора будет достаточно
Ответ 6
Энди - отличный ответ!
Если вы хотите увидеть каждый шаг цикла (с перерывами), попробуйте это:
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]))