Ряд числа фибоначчи питон

Последовательность Фибоначчи в Python

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

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

У неизменяемой последовательность должно быть две основные возможности:

  • Возвращать количество элементов последовательности.
  • Возвращать элемент по заданному индексу или вызывать ошибку IndexError, если индекс выходит за границы последовательности.

Если объект удовлетворяет вышеуказанным требованиям, получится производить следующие действия:

  • Использовать синтаксис квадратных скобок [] для получения элемента по индексу.
  • Перебирать элементы последовательности: например, с помощью цикла for.

Чтобы реализовать перечисленные выше возможности, нужно создать следующие методы:

  • __getitem__ — возвращает элемент по заданному индексу.
  • __len__ — возвращает длину последовательности.

1) Метод __getitem__

У метода __getitem__ должен быть аргумент index , который является целым числом. Метод __getitem__ должен вернуть элемент из последовательности на основе указанного индекса.

Диапазон значений index : от нуля до length — 1 . Если индекс выходит за границы, метод __getitem__ должен выдать исключение IndexError.

Метод __getitem__ может принимать объект среза для слайсинга.

2) The __len__ method

Если у пользовательской последовательности есть метод __len__ , вы можете использовать встроенную функцию len() , чтобы получить количество элементов последовательности.

Последовательность Фибоначчи

Последовательность Фибоначчи примерно в 1170 году открыл Леонардо Фибоначчи, итальянский математик.

В последовательности Фибоначчи каждое число является суммой двух предшествующих ему чисел. Например:

Последовательность Фибоначии можно задать следующей формулой:

f(1) = 1
f(2) = 1
f(n) = f(n-1) + f(n-2) если n > 2

В некоторые источниках сказано, что последовательность Фибоначчи начинается с нуля, а не с 1, как сейчас. То есть вот так:

Но мы будем придерживаться исходной последовательности Фибоначчи, которая начинается с единицы.

Чтобы вычислить число Фибоначчи в Python, нужно создать такую рекурсивную функцию:

В этой рекурсивной функции fib(1) и fib(2) всегда возвращают 1. А когда n больше 2, fib(n) = fib(n-2) — fib(n-1) .

Добавим print() в начало функции, чтобы посмотреть, как она работает, и вызовем функцию fib() с аргументом 6.

def fib(n): print(f'Считаю число Фибоначчи') if n < 2: return 1 return fib(n-2) + fib(n-1) fin(6)
Считаю 6 число Фибоначчи
Считаю 4 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 3 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 5 число Фибоначчи
Считаю 3 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 4 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 3 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи

Как вы видите, функция fib() часто повторяется.

Читайте также:  Mysql php create column

Например, ей приходится трижды вычислять 3 число Фибоначчи. Это неэффективно.

Чтобы решить эту проблему, в Python есть декоратор под названием lru_cache из модуля functools .

lru_cache позволяет кэшировать результат работы функции. Когда вы передаете тот же аргумент функции, функция просто получает результат из кэша вместо того, чтобы пересчитывать его.

Ниже показано, как использовать декоратор lru_cache для ускорения работы функции fib() :

from functools import lru_cache @lru_cache def fib(n): print(f'Считаю число Фибоначчи') if n < 2: return 1 return fib(n-2) + fib(n-1) fib(6)
Считаю 6 число Фибоначчи
Считаю 4 число Фибоначчи
Считаю 2 число Фибоначчи
Считаю 0 число Фибоначчи
Считаю 1 число Фибоначчи
Считаю 3 число Фибоначчи
Считаю 5 число Фибоначчи

Как вы видите, количество вычислений значительно уменьшилось.

Создаем последовательность Фибоначии

1. Сначала определим класс, реализующий последовательность Фибоначчи:

class Fibonacci: def __init__(self, n): self.n = n

Метод __init__ принимает целое число n , которое задает длину последовательности.

2. Теперь определим статический метод, который вычисляет значение определенного числа Фибоначчи:

@staticmethod @lru_cache(2**16) def fib(n): if n < 2: return 1 return Fibonacci.fib(n-2) + Fibonacci.fib(n-1)

3. Реализуем метод __len__ , чтобы мы могли использовать встроенную функцию len() для получения количества элементов из последовательности Фибоначчи:

def __len__(self): return self.n 

4. Реализуем метод __getitem__ для поддержки индексации с помощью синтаксиса квадратных скобок []:

def __getitem__(self, index): if isinstance(index, int): if index < 0 or index >self.n - 1: raise IndexError return Fibonacci.fib(index)

Метод __getitem__ принимает целое число index. Метод __getitem__ проверяет, является ли индекс целым числом, используя функцию isinstance() .

Если index выходит за границы последовательности, __getitem__ вызовет исключение IndexError. В противном случае он вернет число Фибоначчи индекса.

Соединим все вместе:

from functools import lru_cache class Fibonacci: def __init__(self, n): self.n = n def __len__(self): return self.n def __getitem__(self, index): if isinstance(index, int): if index < 0 or index >self.n - 1: raise IndexError return Fibonacci.fib(index) @staticmethod @lru_cache(2**16) def fib(n): if n < 2: return 1 return Fibonacci.fib(n-2) + Fibonacci.fib(n-1)

Кастомная последовательность Фибоначчи в виде Python-класса готова. Однако вы не сможете просто сохранить этот код в модуле fibonacci.py и использовать его в другом скрипте.

Читайте также:  Jquery ui min css cdn

Давайте разберемся, как использовать созданную последовательность.

Используем последовательность Фибоначии

Ниже показано, как использовать последовательность Фибоначчи из модуля fibonacci.py :

from fibonacci import Fibonacci fibonacci = Fibonacci(10) # используем [] print('Используем последовательность Фибоначчи с помощью []:') print(fibonacci[0]) print(fibonacci[1]) print(fibonacci[2]) print('Используем последовательность Фибоначчи с помощью цикла for:') # используем for for f in fibonacci: print(f)
Используем последовательность Фибоначии с помощью []:
1
1
2
Используем последовательность Фибоначчи с помощью цикла for:
1
1
2
3
5
8
13
21
34
55

Как это работает

  1. Создаем новый экземпляр последовательности Фибоначчи, в котором содержится 10 элементов.
  2. Получаем доступ к элементам последовательности Фибначчи с помощью квадратных скобок [].
  3. Используем последовательность Фибоначии в цикле for.

Добавляем поддержку срезов

Чтобы можно было делать срезы нашей последовательности, как показано ниже,

. нужно добавить соответсвующую логику, которая будет обрабатывать объект среза.

В fibonacci[1:5] аргументом index метода __getitem__ является объект среза, начало которого равно 1, а конец — 5.

Вы можете использовать метод indices() объекта среза, чтобы получить индексы элементов для возврата из последовательности:

indices = index.indices(self.n)

self.n — это длина последовательности, которая будет «нарезана». В данном случае это количество элементов в последовательности Фибоначчи.

Чтобы вернуть список Фибоначчи из среза, вы можете передать индексы в функцию range() и сделать вот так:

[Fibonacci.fib(k) for k in range(*indices)] 

Соберем все вместе:

from functools import lru_cache class Fibonacci: def __init__(self, n): self.n = n def __len__(self): return self.n def __getitem__(self, index): if isinstance(index, int): if index < 0 or index >self.n - 1: raise IndexError return Fibonacci.fib(index) else: indices = index.indices(self.n) return [Fibonacci.fib(k) for k in range(*indices)] @staticmethod @lru_cache def fib(n): if n < 2: return 1 return Fibonacci.fib(n-2) + Fibonacci.fib(n-1)

Теперь можно сделать срез последовательности следующим образом:

from fibonacci import Fibonacci fibonacci = Fibonacci(10) print(fibonacci[1:5])

Что нужно запомнить

  • Для создания кастомной последовательно нужно реализовать методы __len__ и __getitem__ .
  • Метод __getitem__ должен возвращать элемент по заданному индексу или вызывать ошибку IndexError, если индекс выходит за границы последовательности.

СodeСhick.io - простой и эффективный способ изучения программирования.

2023 © ООО "Алгоритмы и практика"

Источник

Числа Фибоначчи: циклом и рекурсией

Числа Фибоначчи – это ряд чисел, в котором каждое следующее число равно сумме двух предыдущих.

Читайте также:  Java vfs to file

Иногда ряд начинают с нуля.

В данном случае мы будем придерживаться первого варианта.

Формула и пример вычисления чисел ряда Фибоначчи

Вычисление n-го числа ряда Фибоначчи с помощью цикла while

Присвоим переменным fib1 и fib2 значения двух первых элементов ряда, то есть единицы.

Получим от пользователя номер элемента, значение которого требуется вычислить. Присвоим номер элемента переменной n .

Поскольку значения первых двух элементов ряда Фибоначчи нам уже известны и вычисления начинаем с третьего, количество проходов по телу цикла должно быть на 2 меньше значения n , то есть n - 2 .

Если пользователь вводит 1 или 2, тело цикла ни разу не выполняется, на экран выводится исходное значение fib2 .

  1. Сложить fib1 и fib2 , присвоив результат переменной для временного хранения данных, например, fib_sum .
  2. Переменной fib1 присвоить значение fib2 .
  3. Переменной fib2 присвоить значение fib_sum .

После окончания работы цикла вывести значение fib2 на экран.

fib1 = 1 fib2 = 1 n = input("Номер элемента ряда Фибоначчи: ") n = int(n) i = 0 while i  n - 2: fib_sum = fib1 + fib2 fib1 = fib2 fib2 = fib_sum i = i + 1 print("Значение этого элемента:", fib2)

Пример выполнения программы:

Номер элемента ряда Фибоначчи: 10 Значение этого элемента: 55
fib1 = fib2 = 1 n = input("Номер элемента ряда Фибоначчи: ") n = int(n) - 2 while n > 0: fib1, fib2 = fib2, fib1 + fib2 n -= 1 print("Значение этого элемента:", fib2)

Вывод ряда чисел Фибоначчи с помощью цикла for

В данном случае выводится не только значение искомого элемента ряда Фибоначчи, но и все числа до него включительно. Для этого вывод значения fib2 помещен в цикл.

fib1 = fib2 = 1 n = int(input()) print(fib1, fib2, end=' ') for i in range(2, n): fib1, fib2 = fib2, fib1 + fib2 print(fib2, end=' ') 
10 1 1 2 3 5 8 13 21 34 55

Рекурсивное вычисление n-го числа ряда Фибоначчи

  1. Если n = 1 или n = 2, вернуть в вызывающую ветку единицу, так как первый и второй элементы ряда Фибоначчи равны единице.
  2. Во всех остальных случаях вызвать эту же функцию с аргументами n - 1 и n - 2. Результат двух вызовов сложить и вернуть в вызывающую ветку программы.
def fibonacci(n): if n in (1, 2): return 1 return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(10))

Допустим, n = 4. Тогда произойдет рекурсивный вызов fibonacci(3) и fibonacci(2). Второй вернет единицу, а первый приведет к еще двум вызовам функции: fibonacci(2) и fibonacci(1). Оба вызова вернут единицу, в сумме будет два. Таким образом, вызов fibonacci(3) возвращает число 2, которое суммируется с числом 1 от вызова fibonacci(2). Результат 3 возвращается в основную ветку программы. Четвертый элемент ряда Фибоначчи равен трем: 1 1 2 3.

Источник

Оцените статью