?

Log in

No account? Create an account

[Python] лево-право в итераторе - Узором созвездий по мантии ночи

13.01.2016, Среда

12:55:00 - [Python] лево-право в итераторе

Previous Entry Поделиться Next Entry

Вот что меня удивляет в синтаксисе питона, так это почему внутри конструкци итератора (оно же list comprehension) в случае "многоэтажного" цикла самым внешним оказывается самый левый, а не самый правый цикл.
При том, что в случае одиночного цикла этот цикл заключает в себе стоящее слева выражение, было бы логично, чтобы при двух циклках правый заключал в себе левый (а тот, в свою очередь, так же заключал в себе стоящее слева выражение).

This entry was originally posted at http://arilou.dreamwidth.org/979356.html. Please comment there using OpenID.

Comments:

[User Picture]
From:phd
Date:13.01.2016 12:18:11

Не надо путать list/dict/set comprehension, generator expression и итераторы

(Link)
Смотрим обычный вложенный цикл:
for i in list1:
    for j in list2:
        result.append(value(i, j))

Теперь запишем это в одну строку (синтаксис не питоновский):
for i in list1 for j in list2 result.append(value(i, j))


А теперь превратим в list comprehension:
result = [value(i, j) for i in list1 for j in list2]

Сразу ясно, что за цикл слева и справа, снаружи и внутри.
(Ответить) (Thread)
[User Picture]
From:arilou
Date:13.01.2016 15:21:14

Re: Не надо путать list/dict/set comprehension, generator expression и итератор

(Link)
Вот в том-то и дело, что ты value(i,j) переносишь с хвоста в начало, а циклы не переносишь.
А вот тебе иной подход.
Берём, допустим list comprehension по одной строке row:
[value(row, col) for col in xrange(max_col)]
Теперь хотим сделать такое со всеми строками:
[[value(row, col) for col in xrange(max_col)] for row in xrange(max_row)]
Но это у нас будет список списков. А если хотим просто один список получить (но в том же порядке, внешний цикл по строкам)? Да, можно воспользоваться иным средством, например itertools.chain. Но было бы удобно и наглядно, если бы можно было просто убрать в записи выше внутренние [], и получить тот же порядок исполнения циклов, но собирающий полученные значения в один список.
(Ответить) (Parent) (Thread)
[User Picture]
From:phd
Date:13.01.2016 16:35:45
(Link)
Не было бы это ни удобно (потому что редко когда надо), ни наглядно, ибо тогда сломалась бы наглядность соответствия обычным вложенным циклам.
(Ответить) (Parent) (Thread)
[User Picture]
From:arilou
Date:15.01.2016 12:09:12
(Link)
Ну, видимо, про наглядность -- вопрос субъективный.
Для меня наглядность как раз сохраняется.
В обычном цикле вложенное -- ниже (и сдвинуто правее), т.е. чтение идёт от самого внешнего круга итерации -- к телу самого внутреннего цикла. Т.е. "снаружи - внутрь".
В list comprehension одноуровневом я читаю "изнутри -- наружу" (сначала прочитыаю что за данные, потом в какой итерации они генерятся.
А в многоуровневом сейчас получается, что глаз изнутри прыгает сначала совсем наружу, на самую внешнюю итерацию, а потом постепенно погружается внутрь.
Способ я и такой конечно усвоить способен. Но привыкнуть прочтения беглого потребуется для. ;)
(Ответить) (Parent) (Thread)