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

Одиночная линия, вложенная в петли

Написал эту функцию в python, которая переносит матрицу:

def transpose(m):
    height = len(m)
    width = len(m[0])
    return [ [ m[i][j] for i in range(0, height) ] for j in range(0, width) ]

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

  • Каков порядок выполнения этого цикла for?
  • Если бы у меня был тройной вложенный цикл, какой порядок он выполнил бы?
  • Что будет равным равному безжизненному циклу?

Учитывая,

[ function(i,j) for i,j in object ]
  • Какой тип должен быть объектом, чтобы использовать его для структуры цикла?
  • Каков порядок, в котором я и j назначаются элементам в объекте?
  • Может ли он быть смоделирован другой структурой цикла?
  • Может ли это для цикла быть вложенным с аналогичной или другой структурой для цикла? И как это будет выглядеть?

Дополнительная информация также оценена.

4b9b3361

Ответ 1

Лучшим источником информации является официальный официальный учебник по Python по распознаванию списков. Сопоставления списков почти такие же, как для циклов (конечно, любое понимание списка может быть записано как цикл for), но они часто бывают быстрее, чем использование цикла for.

Посмотрите на это более длинное понимание списка из учебника (часть if фильтрует понимание, только те части, которые передают оператор if, передаются в заключительную часть понимания списка (здесь (x,y)):

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Это точно так же, как этот вложенный цикл цикла (и, как говорится в учебнике, обратите внимание, как порядок for и if одинаковый).

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Основное различие между пониманием списка и циклом for состоит в том, что конечная часть цикла for (где вы что-то делаете) происходит в начале, а не в конце.

На ваши вопросы:

Какой тип должен быть объектом, чтобы использовать это для структуры цикла?

An iterable. Любой объект, который может генерировать (конечный) набор элементов. К ним относятся любой контейнер, списки, наборы, генераторы и т.д.

Каков порядок, в котором я и j назначаются элементам в объекте?

Они назначаются точно в том же порядке, в котором они генерируются из каждого списка, как если бы они находились во вложенном цикле (для вашего первого понимания вы получите 1 элемент для i, тогда каждое значение из j, 2-го элемента в i, то каждое значение из j и т.д.)

Можно ли имитировать другую структуру цикла?

Да, уже показано выше.

Может ли это для цикла быть вложенным с аналогичной или другой структурой для цикла? И как это выглядело бы?

Конечно, но это не отличная идея. Здесь, например, вы получаете список списков символов:

[[ch for ch in word] for word in ("apple", "banana", "pear", "the", "hello")]

Ответ 2

Вам может быть интересен itertools.product, который возвращает итерируемые урожаи значений из всех повторяющихся им итераций. То есть itertools.product(A, B) дает все значения формы (a, b), где значения a берутся от a, а значения b - от b. Например:

import itertools

A = [50, 60, 70]
B = [0.1, 0.2, 0.3, 0.4]

print [a + b for a, b in itertools.product(A, B)]

Отпечатки:

[50.1, 50.2, 50.3, 50.4, 60.1, 60.2, 60.3, 60.4, 70.1, 70.2, 70.3, 70.4]

Обратите внимание, как последний аргумент, переданный itertools.product, является "внутренним". Как правило, itertools.product(a0, a1, ... an) равно [(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]

Ответ 3

Прежде всего, ваш первый код не использует цикл for per se, но список.

  • Было бы эквивалентно

    для j в диапазоне (0, ширина):   для я в диапазоне (0, высота):       м [I] [J]

  • Точно так же, как правило, он располагается как петли, справа налево. Но синтаксис понимания списка сложнее.

  • Я не уверен, что этот вопрос задает


  • Любой итеративный объект, который дает итеративные объекты, которые дают ровно два объекта (что будет иметь рот - i.e [(1,2),'ab'])

  • Порядок, в котором объект дает на итерации. i переходит на первый выход, j второй.

  • Да, но не так красиво. Я считаю, что это функционально эквивалентно:

    l = list()
    for i,j in object:
        l.append(function(i,j))
    

    или даже лучше использовать map:

    map(function, object)
    

    Но, конечно, функция должна была бы получить i, j.

  • Разве это не тот же вопрос, что и 3?