В Python там более легкий способ записать 6 вложенных для циклов?

Я преподавал эти вещи, когда я был Дополнением в Орегонском технологическом институте. Им преподают, просто редко.

38
задан RichieHindle 14 August 2009 в 23:33
поделиться

11 ответов

Если вы часто повторяете декартово произведение, как в вашем примере, вы можете исследовать itertools.product Python 2.6 или написать свой собственный, если вы используете более ранний Python.

from itertools import product
for y, x in product(range(3), repeat=2):
  do_something()
  for y1, x1 in product(range(3), repeat=2):
    do_something_else()
58
ответ дан 27 November 2019 в 03:09
поделиться

Это довольно часто встречается при циклическом переходе по многомерным пространствам. Мое решение:

xy_grid = [(x, y) for x in range(3) for y in range(3)]

for x, y in xy_grid:
    # do something
    for x1, y1 in xy_grid:
        # do something else
14
ответ дан 27 November 2019 в 03:09
поделиться

Столкнувшись с такой программной логикой, я, вероятно, разбил бы последовательность циклов на две или более отдельных функций.

Другой метод в Python - использовать понимание списков по возможности вместо петли.

10
ответ дан 27 November 2019 в 03:09
поделиться

Предполагая, что каждый цикл имеет какое-то независимое значение, разбейте их на именованные функции:

def do_tigers():
    for x in range(3):
        print something

def do_lions():
    do_lionesses()
    for x in range(3):
        do_tigers()

def do_penguins():
    for x in range(3):
        do_lions()

..etc.

Возможно, я мог бы выбрать лучшие имена. 8 -)

8
ответ дан 27 November 2019 в 03:09
поделиться

Технически вы можете использовать itertools.product , чтобы получить декартово произведение N последовательностей, и перебрать его:

 for y, x, y1, x1 in itertools.product(range(3), repeat=4):
   do_something_else()

Но я не думаю, что это действительно выигрывает у вас что-нибудь с точки зрения удобочитаемости.

5
ответ дан 27 November 2019 в 03:09
поделиться

Итераторы Python и, в частности, генераторы, существуют именно для того, чтобы позволить хороший рефакторинг сложных циклов. Конечно, сложно сделать абстракцию из простого примера, но если предположить, что 3 должен быть параметром (может быть, весь диапазон (3) должен быть?), И две функции, которые вы вызываете, нуждаются в некоторых параметрах, которые являются переменными цикла, вы можете выполнить рефакторинг кода:

  for y in range(3):
    for x in range(3):
      do_something(x, y)
      for y1 in range(3):
        for x1 in range(3):
          do_something_else(x, y, x1, y1)

, например, в:

def nestloop(n, *funcs):
  head = funcs[0]
  tail = funcs[1:]
  for y in range(n):
    for x in range(n):
      yield head, x, y
      if tail:
        for subtup in nestloop(n, *tail):
           yield subtup[:1] + (x, y) + subtup[1:]

for funcandargs in nestloop(3, do_something, do_something_else):
  funcandargs[0](*funcandargs[1:])

Точный вид рефакторинга, несомненно, необходимо будет настроить для ваших конкретных целей, но общий замечание о том, что итераторы (и обычно на самом деле просто простые генераторы) обеспечивают очень хороший рефакторинг циклов, остается - вся логика циклов находится внутри генератора,

4
ответ дан 27 November 2019 в 03:09
поделиться

Лично я считаю, что вы, вероятно, делаете что-то не так, если у вас 6 вложенных циклов ...

Тем не менее, функциональная декомпозиция - это то, что вы ищете. Выполните рефакторинг, чтобы некоторые циклы выполнялись при отдельных вызовах функций, а затем вызовите эти функции.

3
ответ дан 27 November 2019 в 03:09
поделиться

Судя по вашему коду, вы хотите выполнить операцию со всеми возможными парами точек, где x и y находятся в диапазоне 0..2.

Для этого :

for x1,y1,x2,y2 in itertools.product(range(3), repeat=4):
    do_something_with_two_points(x1,y1,2,y2)

Операция do_something_with_two_points будет вызываться 81 раз - один раз для каждой возможной комбинации точек.

3
ответ дан 27 November 2019 в 03:09
поделиться

Вы изучали List Components?

Что-то вроде:

[do_something() for x in range(3) for y in range(3)]
2
ответ дан 27 November 2019 в 03:09
поделиться

Этот способ выглядит довольно простым и легким. Вы говорите, что хотите обобщить на несколько уровней циклов ... не могли бы вы привести пример из реальной жизни?

Другой вариант, о котором я мог бы подумать, - это использовать функцию для генерации параметров, а затем просто применять их в цикле

def generate_params(n):
    return itertools.product(range(n), range(n))

for x,y in generate_params(3):
    do_something()
2
ответ дан 27 November 2019 в 03:09
поделиться

вы также можете использовать map () function

2
ответ дан 27 November 2019 в 03:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: