Альтернатива вложению циклов в Python

Я читал, что одно из основных убеждений Python - плоская> вложенность. Однако, если у меня есть несколько подсчитываемых переменных, какова альтернатива множеству циклов for? Мой код предназначен для подсчета сумм сетки и выглядит следующим образом:

def horizontal():
    for x in range(20):
        for y in range(17):
            temp = grid[x][y: y + 4]
            sum = 0
            for n in temp:
                sum += int(n)
            print sum # EDIT: the return instead of print was a mistype

Мне кажется, что он слишком сильно вложен. Во-первых, то, что считается в Python множеством вложенных циклов (я наверняка видел раньше 2 вложенных цикла). Во-вторых, если он слишком сильно вложен, каков альтернативный способ написать этот код?


person davenz    schedule 17.12.2012    source источник
comment
Здесь вы ищете itertools.product.   -  person Ashwini Chaudhary    schedule 17.12.2012
comment
Вы уверены, что ваш оператор возврата находится внутри 2 циклов for?   -  person 0xc0de    schedule 17.12.2012
comment
0xc0de, это была опечатка (я имел в виду печать), спасибо, что указали на это   -  person davenz    schedule 17.12.2012
comment
@AshwiniChaudhary Вы уверены, что ваш оператор return находится внутри 2 циклов for?   -  person J.Do    schedule 08.11.2017


Ответы (3)


from itertools import product

def horizontal():
    for x, y in product(range(20), range(17)):
        print 1 + sum(int(n) for n in grid[x][y: y + 4])

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

person John La Rooy    schedule 17.12.2012
comment
Я бы использовал xrange вместо range. Я также согласен с тем, что return внутри цикла - это ошибка. - person ; 17.12.2012
comment
@Balthamos, для небольших диапазонов range быстрее, а в Python3 нет xrange. OP не упоминает, какую версию они используют - person John La Rooy; 17.12.2012
comment
Да неужели? Спасибо, я этого не знал. - person ; 17.12.2012
comment
Вы можете просто наклеить возврат в строке расчета суммы. Как вы правильно заметили, return остановит выполнение, и будет выполнен следующий оператор после вызова. Поскольку переменная my_sum не нужна (ее нельзя использовать после обратного вызова), ее не нужно объявлять. Короче return 1 + sum(int(n) for n in grid[x][y: y + 4]) - person Burhan Khalid; 17.12.2012
comment
@BurhanKhalid, OP пояснил, что там должен быть только print - person John La Rooy; 17.12.2012
comment
Ах хорошо. Не рекомендуется в качестве конечного результата печатать фигню в методах. Это заставляет метод возвращать None и удивляет, если вы делаете print horizontal() - person Burhan Khalid; 17.12.2012
comment
Этот раздел кода еще не закончен. Печать просто проверяет, что он делает все суммы, и позже я потребую, чтобы он возвращал только самые высокие - person davenz; 17.12.2012
comment
@davenz, функция max может тебе в этом помочь. Вам просто нужно немного изменить положение вещей - person John La Rooy; 17.12.2012

grid = [range(20) for i in range(20)]
sum(sum( 1 + sum(grid[x][y: y + 4]) for y in range(17)) for x in range(20))

Вышеупомянутые выходные данные 13260 для конкретной сетки, созданной в первой строке кода. Он использует sum() три раза. Самая внутренняя сумма складывает числа в grid[x][y: y + 4] плюс немного странное начальное значение sum = 1, показанное в коде вопроса. Средняя сумма складывает эти значения для 17 возможных значений y. Внешняя сумма складывает средние значения по возможным значениям x.

Если элементы сетки представляют собой строки, а не числа, замените
sum(grid[x][y: y + 4])
на
sum(int(n) for n in grid[x][y: y + 4]

person James Waldby - jwpat7    schedule 17.12.2012

Вы можете использовать словарь, чтобы значительно оптимизировать производительность

Это еще один пример:

locations = {}
for i in range(len(airports)):
    locations[airports["abb"][i][1:-1]] = (airports["height"][i], airports["width"][i])

for i in range(len(uniqueData)):
    h, w = locations[uniqueData["dept_apt"][i]]
    uniqueData["dept_apt_height"][i] = h
    uniqueData["dept_apt_width"][i] = w
person Jakub Bares    schedule 12.10.2016