избегайте вложенного цикла при добавлении элементов в повторяющийся список

#python #python-3.9

Вопрос:

Я стараюсь избегать вложенных циклов в Python. В общем, мне удается сделать это с помощью какой itertools -то утилиты, zip функции и т. Д. Однако есть еще один случай, для которого мне не удалось устранить классическую структуру вложенного цикла: случай, когда при повторении списка вы хотите добавить элементы в тот же список и хотите, чтобы эти элементы были частью цикла.

Вот пример:

 a = [1,5,21]

for i1, val1 in enumerate(a):
  for i2 in range(i1 1, len(a)):
    val2 = a[i2]
    if (val1 val2)%3==0 and abs(val1-val2)<30:
      a.append(val1 val2)
    
print("final", a) #[1, 5, 21, 6, 27, 33, 60, 93]
 

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

Комментарии:

1. Я бы сказал, что вы не можете, и это совсем не проблема, иногда вам нужно 2 вложенных цикла, иногда 3, это нормально

2. Почему вы избегаете вложенных циклов? По какой-то конкретной причине?

Ответ №1:

Вот решение с циклом while.

 expected = [1, 5, 21, 6, 27, 33, 60, 93]
a = [1,5,21]

val1, val2 = a[0], a[1]
idx = 0
while abs(val1-val2) < 30: 
    if (val1   val2) % 3 == 0:
        a.append(val1 val2)
    idx  = 1
    val1, val2 = a[idx], a[idx 1]
a == expected # True
 

Комментарии:

1. Это идеально.

Ответ №2:

Есть ли какая-то конкретная причина, по которой вы не используете подход с вложенным циклом?

Однако, исходя из предположения, что вы хотите попробовать что-то помимо цикла. Я создал аналогичную программу с использованием рекурсии. Надеюсь, это поможет! 😊

 def fn_recur(a,i1,i2):
    val1 = a[i1]
    val2 = a[i2]
    if (val1 val2)%3 == 0 and abs(val1-val2) < 30:
      a.append(val1 val2)
    if(i2 1 < 3):
        i2 = i2 1
    elif(i1 2 < len(a)):
        i1 = i1 1
        i2 = i1 1
    else:
        print(a)
        return a
    fn_recur(a,i1,i2)
fn_recur([1,5,21],0,1)
#output [1, 5, 21, 6, 27, 33, 60, 93]