- Последовательность Фибоначчи в Python
- 1) Метод __getitem__
- 2) The __len__ method
- Последовательность Фибоначчи
- Создаем последовательность Фибоначии
- Используем последовательность Фибоначии
- Как это работает
- Добавляем поддержку срезов
- Что нужно запомнить
- Числа Фибоначчи через рекурсию в Python
- Ряд Фибоначчи
- Преимущества рекурсии
- Недостатки рекурсии
- Числа Фибоначчи на Python
- Введение
- Числа Фибоначчи циклом while
- Числа Фибоначчи циклом for
- Числа Фибоначчи рекурсией
- Заключение
Последовательность Фибоначчи в 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() часто повторяется.
Например, ей приходится трижды вычислять 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 и использовать его в другом скрипте.
Давайте разберемся, как использовать созданную последовательность.
Используем последовательность Фибоначии
Ниже показано, как использовать последовательность Фибоначчи из модуля 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
Как это работает
- Создаем новый экземпляр последовательности Фибоначчи, в котором содержится 10 элементов.
- Получаем доступ к элементам последовательности Фибначчи с помощью квадратных скобок [].
- Используем последовательность Фибоначии в цикле 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 © ООО "Алгоритмы и практика"
Числа Фибоначчи через рекурсию в Python
Функции, реализованные с использованием рекурсии, могут быть использованы с помощью циклов. В основном, когда вещь определяется сама по себе, происходит рекурсия. Акроним PHP – препроцессор гипертекста PHP. Это пример рекурсии. В python рекурсия происходит, когда функция определяется сама по себе. Структура рекурсивной функции приведена ниже.
def recursive_function(arguments): #check for the terminating condition if breaking_condition == True : #Calculate result return result #perform some operation with the arguments #call the function itself to perform further operation return recursive_function(arguments_for_further_operation)
Ряд Фибоначчи
Ряд Фибоначчи – это в основном последовательность. В этой последовательности каждое число является суммой двух предыдущих номеров этой последовательности. Первые два числа ряда – это либо 0 и 1, либо 1 и 1. Мы будем рассматривать 0 и 1, как первые два числа в нашем примере. Итак, первые несколько цифр в этой серии.
- 1-е число Фибоначчи = 0 (по предположению);
- 2-е число Фибоначчи = 1 (по предположению);
- 3-е число Фибоначчи = 1-е + 2-е = 0 + 1 = 1;
- 4-е число Фибоначчи = 2-е + 3-е = 1 + 1 = 2;
- 5-е число Фибоначчи = 3-е + 4-е = 1 + 2 = 3;
- 6-е число Фибоначчи = 4-е + 5-е = 2 + 3 = 5;
- Итак, n-е число Фибоначчи = (n-1) -ое число Фибоначчи + (n-2) -ое число Фибоначчи.
Итак, ниже приведен код для реализации функции Фибоначчи:
def Fibonacci( pos ): #check for the terminating condition if posПриведенный выше код вычислит число Фибоначчи с использованием техники рекурсии. Следующее изображение поможет вам более эффективно понять концепцию. На этом рисунке синие прямоугольники –это вызовы функций, в которых выполняются условия завершения.
Преимущества рекурсии
Реализация чего-либо с использованием рекурсии требует меньше усилий. Код, который вы написали с использованием рекурсии, будет сравнительно меньше, чем код, реализованный с помощью циклов. Опять же, код, написанный с использованием рекурсии, также легче понять.
Недостатки рекурсии
Рекурсия требует большего количества вызовов функций. Каждый сохраняет некоторую переменную состояния в стеке программы. Если ваш код требует слишком много вызовов функций, он потребляет слишком много памяти. Таким образом, могут быть некоторые возможности вызвать переполнение памяти, если ваш код не так эффективен.
Опять же, для вызова функции требуется некоторое время, если задача функции выполнена, она вызывает родительскую функцию, что также вызывает некоторое время для повторного выполнения данной функции из предыдущего состояния. Таким образом, рекурсивная функция требует больше времени для выполнения своей задачи.
Кроме того, отладка рекурсивной функции в большинстве случаев сложнее.
Числа Фибоначчи на Python
Статьи
Введение
В статье разберём 3 способа получения ряда Фибоначчи на Python. Первые два способа будут с использованием циклов, а третий – рекурсивный.
Числа Фибоначчи – бесконечная последовательность чисел, каждое из которых является суммой двух предыдущих и так до бесконечности.
Числа Фибоначчи циклом while
Для начала создадим переменную, в которую будет вводиться длина ряда:
n = int(input('Введите длину ряда: '))
Далее создадим две переменные (f1 и f2), которые будут равняться начальным единицам и выведем их:
Создадим переменную i, которая будет равняться двум:
Добавим цикл, который не закончится, пока переменная i будет меньше переменной n:
Числа Фибоначчи на Python:
n = int(input('Введите длину ряда: ')) f1 = f2 = 1 print(f1, f2, end=' ') i = 2 while i < n: f1, f2 = f2, f1 + f2 # f1 приравнивается к f2, f2 приравнивается к f1 + f2 print(f2, end=' ') # Выводится f2 i += 1 print()
Числа Фибоначчи циклом for
Создадим переменную, в которую будет вводиться длина ряда:
n = int(input('Введите длину ряда: '))
Далее создадим две переменные (f1 и f2), которые будут равняться начальным единицам и выведем их:
Добавим цикл, который начинается с 2, и заканчивается на n:
for i in range(2, n): f1, f2 = f2, f1 + f2 # f1 приравнивается к f2, f2 приравнивается к f1 + f2 print(f2, end=' ') # Выводится f2
Числа Фибоначчи на Python:
n = int(input('Введите длину ряда: ')) f1 = f2 = 1 print(f1, f2, end=' ') for i in range(2, n): f1, f2 = f2, f1 + f2 print(f2, end=' ')
Числа Фибоначчи рекурсией
Для начала создадим рекурсивную функцию, назовём её fibonacci и добавим ей параметр n:
Добавим условие, что если n = 1, или n = 2, то возвращается единица, так как первый и второй элементы ряда Фибоначчи равны единице. Если же условие не срабатывает, то элементы складываются:
def fibonacci(n): if n == 1 or n == 2: # Если n = 1, или n = 2, вернуть в вызывающую ветку единицу, так как первый и второй элементы ряда Фибоначчи равны единице. return 1 return fibonacci(n - 1) + fibonacci(n - 2)
Числа Фибоначчи на Python:
def fibonacci(n): if n == 1 or n == 2: return 1 return fibonacci(n - 1) + fibonacci(n - 2) n = int(input()) print(fibonacci(n))
Заключение
В данной статье мы научились вычислять n-ное число ряда Фибоначчи на Python. Надеюсь Вам понравилась статья, удачи! 🙂