1

Тема: Цикл For при визначенні значення числа у послідовності Фібоначчі.

Завдання:
За заданим числом n (номер числа) у послідовності Фібоначчі потрібно визначити значення цього числа.

Послідовність Фібоначчі:
Закономірність чисел, які при постановці в ряд утворюють лінію цифр, кожна з яких є сумою двох попередніх чисел.
Іншими словами, послідовність Фібоначчі виглядає так: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 і так далі.

Розв'язок задачі:

n = int(input())
if n == 0:
    print(0)
else:
    a, b = 0, 1
    for i in range(2, n + 1):
        a, b = b, a + b
    print(b)

Я не можу зрозуміти як працює цикл For у цій програмі. Зрозуміло, якщо є одна змінна в інших програмах, але якщо дві, a  і  b. Функція range генерує значення чисел від двійки до n + 1, не зрозуміло, як ці числа присвоюються змінним a і b.

Подякували: koala1

2 Востаннє редагувалося mamkin haker (25.10.2021 10:46:05)

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

не зрозуміло, як ці числа присвоюються змінним a і b.

а ніяк, це просто цикл
ось приклад

n = 10

# цикл вайл
i = 2
while (i < n + 1):
    print(i, end = ' ')
    i += 1

print('\n')

#цикл фор
for i in range(2, n + 1):
    print(i, end = ' ')

як ми бачимо, ці 2 цикла однакові, але for більш компактніший

якщо ми беремо перемінні "a" та "b" то на них переменна "i" зовсім ніяк не впливає, це ж всього навсього цикл...

Подякували: oland19791

3 Востаннє редагувалося mamkin haker (25.10.2021 13:06:14)

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

#щас пофікшу
koala уже замість мене  про range(n - 1) написав, дякую йому :3

Подякували: oland19791

4 Востаннє редагувалося koala (25.10.2021 10:51:06)

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

Цикл - це просто цикл. Причому він дещо надмірний - ми ж не використовуємо всередині змінну i, так? Отже, можемо записати замість i _ на позначення непотрібності цієї змінної

    for _ in range(2, n + 1):
        a, b = b, a + b

чи навіть змінити межі ітерації, залишивши ту саму кількість:

    for _ in range(n - 1):
        a, b = b, a + b

Ці варіації абсолютно точно тотожні вашому коду.
Гадаю, вас більше цікавить не те, що відбувається з циклом, а те, що відбувається В циклі. Цей запис дещо заскладний для новачків; ідея в тому, що права сторона обчислюється перед присвоюванням значень, тому a набуває старого значення b, а b - a+b. Аналогічно можна було б написати:

    for _ in range(n - 1):
        t = (b, a+b) #кортеж, тьюпл
        a = t[0]
        b = t[1]

або навіть

    for _ in range(n - 1):
        t = a
        a = b
        b = t + b

Цей код також еквівалентний за результатом роботи вашому.

Подякували: mamkin haker, oland19792

5

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

Власне, у вас є два рядки з однаковим присвоюванням:

a, b = 0, 1

та

a, b = b, a + b

Другий трохи заплутаніший, але принцип той самий. Про всяк випадок - це зветься "деструктуризацією" (destructuring), бо структура даних (у ньому випадку кортеж) розкладається по змінних.

Подякували: oland1979, Jarko2

6

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

Питання стосується кортежного присвоєння (tuple assignment). Воно робить приблизно те ж саме, що декілька присвоєнь, але є відмінності.

a,b = 0,1

можна переписати як

a=0
b=1

але це простий випадок, де змінні з лівої частини не з'являються у правій, тому не впливають на результат. Насправді ж там відбуваються трохи складніші дії:

tmp=(0, 1) # тимчасова змінна, якій присвоюється кортеж. Дужки необов'язкові: tmp=0, 1 працюватиме так само.
a=tmp[0]
b=tmp[1]

Тобто, спершу обчислюється вся права частина виразу й записується в тимчасову змінну, потім з неї по порядку вибираються значення й записуються у змінні в лівій частині виразу. В цьому випаддку, на результат це не впливає, але ось у наступному це вже треба враховувати.

a, b = b, a + b

можна переписати лише так:

tmp= b, a+b
a=tmp[0]
b=tmp[1] 

Просто запис з кортежним присвоєнням коротший, тому в мовах, де він є, частіше використовують його.

Зверніть увагу: оскільки обидві змінні з'являються і в праій, і в лівій частині, ми не можемо обійтися без тимчасової змінної (як у першому випадку), бо це вплине на результат:

a=b     # старе значення змінної a стирається раніше, ніж треба, тому наступний рядок
b=a+b  # робитиме те ж саме, що b=b+b

Також кортежне присвоєння часто використовують, щоб обміняти значення двох змінних:

x=10
y=20
print('x =', x, ' y =', y) # виведе x = 10 y = 20
x,y = y,x # обмін
print('x =', x, ' y =', y) # виведе x = 20 y = 10

Без нього, обмін довелося б робити з використанням тимчасової змінної:

tmp=y,x
x=tmp[0]
y=tmp[1]

Або так:

tmp=y
y=x
x=tmp

Кортежне присвоєння дозволяє записати це коротше й інтуїтивно зрозуміліше.

Подякували: oland19791

7

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

mamkin haker написав:

#щас пофікшу
koala уже замість мене написав, дякю йому :3

Дуже дякую за відповідь.

8

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

koala написав:

Власне, у вас є два рядки з однаковим присвоюванням:

a, b = 0, 1

та

a, b = b, a + b

Другий трохи заплутаніший, але принцип той самий. Про всяк випадок - це зветься "деструктуризацією" (destructuring), бо структура даних (у ньому випадку кортеж) розкладається по змінних.

Дуже дякую за відповідь, вникаю.

9

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

P.Y. написав:

Питання стосується кортежного присвоєння (tuple assignment). Воно робить приблизно те ж саме, що декілька присвоєнь, але є відмінності.

a,b = 0,1

можна переписати як

a=0
b=1

але це простий випадок, де змінні з лівої частини не з'являються у правій, тому не впливають на результат. Насправді ж там відбуваються трохи складніші дії:

tmp=(0, 1) # тимчасова змінна, якій присвоюється кортеж. Дужки необов'язкові: tmp=0, 1 працюватиме так само.
a=tmp[0]
b=tmp[1]

Тобто, спершу обчислюється вся права частина виразу й записується в тимчасову змінну, потім з неї по порядку вибираються значення й записуються у змінні в лівій частині виразу. В цьому випаддку, на результат це не впливає, але ось у наступному це вже треба враховувати.

a, b = b, a + b

можна переписати лише так:

tmp= b, a+b
a=tmp[0]
b=tmp[1] 

Просто запис з кортежним присвоєнням коротший, тому в мовах, де він є, частіше використовують його.

Зверніть увагу: оскільки обидві змінні з'являються і в праій, і в лівій частині, ми не можемо обійтися без тимчасової змінної (як у першому випадку), бо це вплине на результат:

a=b     # старе значення змінної a стирається раніше, ніж треба, тому наступний рядок
b=a+b  # робитиме те ж саме, що b=b+b

Також кортежне присвоєння часто використовують, щоб обміняти значення двох змінних:

x=10
y=20
print('x =', x, ' y =', y) # виведе x = 10 y = 20
x,y = y,x # обмін
print('x =', x, ' y =', y) # виведе x = 20 y = 10

Без нього, обмін довелося б робити з використанням тимчасової змінної:

tmp=y,x
x=tmp[0]
y=tmp[1]

Або так:

tmp=y
y=x
x=tmp

Кортежне присвоєння дозволяє записати це коротше й інтуїтивно зрозуміліше.

10 Востаннє редагувалося oland1979 (25.10.2021 16:16:58)

Re: Цикл For при визначенні значення числа у послідовності Фібоначчі.

Дякую всім за витрачений час і пояснення. Все зрозуміло.