- Последовательность Фибоначчи в Python
- 1) Метод __getitem__
- 2) The __len__ method
- Последовательность Фибоначчи
- Создаем последовательность Фибоначии
- Используем последовательность Фибоначии
- Как это работает
- Добавляем поддержку срезов
- Что нужно запомнить
- Числа Фибоначчи: циклом и рекурсией
- Вычисление n-го числа ряда Фибоначчи с помощью цикла while
- Вывод ряда чисел Фибоначчи с помощью цикла for
- Рекурсивное вычисление n-го числа ряда Фибоначчи
- Числа Фибоначчи на 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 © ООО "Алгоритмы и практика"
Числа Фибоначчи: циклом и рекурсией
Числа Фибоначчи – это ряд чисел, в котором каждое следующее число равно сумме двух предыдущих.
Иногда ряд начинают с нуля.
В данном случае мы будем придерживаться первого варианта.
Вычисление n-го числа ряда Фибоначчи с помощью цикла while
Присвоим переменным fib1 и fib2 значения двух первых элементов ряда, то есть единицы.
Получим от пользователя номер элемента, значение которого требуется вычислить. Присвоим номер элемента переменной n .
Поскольку значения первых двух элементов ряда Фибоначчи нам уже известны и вычисления начинаем с третьего, количество проходов по телу цикла должно быть на 2 меньше значения n , то есть n - 2 .
Если пользователь вводит 1 или 2, тело цикла ни разу не выполняется, на экран выводится исходное значение fib2 .
- Сложить fib1 и fib2 , присвоив результат переменной для временного хранения данных, например, fib_sum .
- Переменной fib1 присвоить значение fib2 .
- Переменной 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-го числа ряда Фибоначчи
- Если n = 1 или n = 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.
Числа Фибоначчи на 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. Надеюсь Вам понравилась статья, удачи! 🙂