У нас есть простой список:
x = [1, 2, 3, 4, 5, 6, 7]
Мы без проблем можем изменить любой элемент списка по индексу:
x[0] = 99 # x == [99, 2, 3, 4, 5, 6, 7]
Рассмотрим следующий код:
x = [1, 2, 3, 4, 5, 6, 7]
y = x
x[0] = 99
print(y) # y == [99, 2, 3, 4, 5, 6, 7]
Следуя обычной логике, можно предположить что '
y
' должен содержать в себе изначальное состояние списка 'x
'. Но в python, если мы напрямую присваиваем переменной список без дополнительных манипуляций, то эта переменная не получает копию списка, она получает ссылку на присваиваемый список.Что бы копировать список, можно в момент присваиваний сделать срез для списка '
x
', вот так: y = x[:]
. Тогда 'y
' получит копию списка 'x
', а не ссылку на него.Good coding
#list #python #5min_py
Please open Telegram to view this post
VIEW IN TELEGRAM
Или генератор списка на русском.
В одной задаче нужно было создавать и наполнять список получив предварительно каждое значение из пользовательского ввода ( input ). Моё решение выглядело так:
villages_count = int(input())
villages = []
for _ in range(villages_count):
village = int(input())
villages.append(village)
Но пять строк магическим образом могут превратиться в две:
villages_count = int(input())
villages = [int(input()) for _ in range(villages_count)]
Подробнее о теме можно почитать тут — Руководство по использованию list comprehension
Good coding
#list #python #5min_py
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Задача: Баскетбольный матч
Сложность: 7 / 10 Оригинал: https://dmoj.ca/problem/coci18c2p1 -------------------- Мы наблюдаем баскетбольным матчем, где друг-другу противостоят две великих команды: команда A и команда B. Переменные Нам известно в какую секунду и сколько очков набрала…
Метод
insert()
. Работает он просто: первым параметром передаём индекс, по которому будет находится новый элемент, а вторым параметром передаём сам элемент.my_list = [1, 2, 3, 5]
my_list.insert(3, 4)
print(my_list)
# output [1, 2, 3, 4, 5]
Если следовать простой логике, то можно подумать, что число 4 должно заменить число 5. Но на самом деле, если по указанному индексу находится элемент, то индекс этого элемента и всех элементов после него увеличивается на 1. В наше случае индекс числа 5 становится 4, а третий индекс занимает число 4.
Мы можем добавить элемент с помощью среза.
my_list = [1, 2, 3, 5]
my_list[3:3] = [4]
print(my_list)
# output [1, 2, 3, 4, 5]
Что бы это работало, нужно соблюсти два условия:
1. В срезе и до и после двоеточия должно быть одно и то же число, которое определяет необходимый индекс
2. Присваиваемый элемент должен быть итерируемым. В нашем случае мы оборачиваем четверку в список
Операции со срезами могут изменять последовательность в списке, но только при условии, что мы присваиваем другой итерируемый объект, такой как список. Срез возвращает не один элемент, а последовательность элементов (список), и, соответственно, при присвоении Python ожидает последовательность в качестве значения.
Первый вариант более академичный, второй лаконичный, но любой из них правильный.
———
Good coding
#python #5min_py #list
Please open Telegram to view this post
VIEW IN TELEGRAM
Многие реки берут своё начало в горах, когда множество маленьких ручьев объединяются в один бурный поток. В этой задаче нам предстоит смоделировать природное явление на уровне кода.
Сложность для junior: 5 / 10
Задача с решением на русском здесь
* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.
———
Good coding
#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Задача: Журчащие ручьи
Сложность: 5 / 10 Оригинал: https://dmoj.ca/problem/ccc00s2 Несколько ручьев сбегает по склону горы. Склон горы очень каменистый, поэтому ручьи много раз разделяются и воссоединяются. У подножия горы несколько ручьев превращаются в реки. Ваша задача - вычислить…
В процессе разработки вы в любом случае столкнетесь с ситуацией, когда с каждым элементом итерируемого объекта нужно будет совершить одно и то же действие.
Предположим что в ходе работы разработчик получает список чисел —
numbers = [5, 5, 10, 25, 35, 70]
Что бы работать дальше с этим списком, необходимо преобразовать его в строку. Если попробовать преобразовать напрямую, то код 'упадет' с ошибкой:
numbers = [5, 5, 10, 25, 35, 70]
str_numbers = ' '.join(numbers)
# >>> TypeError: sequence item 0: expected str instance, int found
Очевидный способ решения — это пробежаться циклом for по всем элементам списка:
numbers = [5, 5, 10, 25, 35, 70]
str_streams = [str(number) for number in numbers]
string = ' '.join(str_streams)
print(string)
# >>> 5 5 10 25 35 70
Можно остановиться и на таком варианте, так как это более чем хорошее решение. Но есть более элегантный способ, мимо которого не хочется проходить.
Так как здесь затрагивается часть идеи функционального программирования, советую почитать об этом стиле на странице официального источника
Посмотрим на преобразованный код:
numbers = [5, 5, 10, 25, 35, 70]
string = ' '.join(map(str, numbers))
print(string)
# >>> 5 5 10 25 35 70
Выглядит не плохо, мы избавились от одной строки, но код стал даже более очевидным. Что в нашем случае делает map()? Буквально принимает два аргумента: функцию и итерируемый объект.
Функция
map()
применяет переданную в параметрах функцию к каждому элементу переданного в параметрах итерируемого объекта, после чего возвращает преобразованный итерируемый объект
Для этого короткого примера не потребуется развернутого объяснения. По сути, если словами выразить команду
map(str, numbers)
, то получится: преобразуй в строку каждое число в списке numbers с помощью функции str.[WARN] Функция передаваемая в параметрах должна передаваться без вызова, то есть без скобок. Если мы передадим и сразу вызовем функцию, то произойдет ошибка:
numbers = [5, 5, 10, 25, 35, 70]
string = ' '.join(map(str(), numbers))
print(string)
# >>> TypeError: 'str' object is not callable
Функция map позволяет делать больше, чем можно описать в посте. Предлагаю особо любопытствующим почитать long read на тему.
———
Good coding
#python #function #5min_py #map
Please open Telegram to view this post
VIEW IN TELEGRAM
Python documentation
Functional Programming HOWTO
Author, A. M. Kuchling,, Release, 0.32,. In this document, we’ll take a tour of Python’s features suitable for implementing programs in a functional style. After an introduction to the concepts of ...
В Python блок
else
может использоваться не только в условных конструкциях if
, но и с циклами for
и while
. Блок else
в цикле выполняется, если цикл завершился "нормально", то есть без прерывания с помощью оператора break
. Если же цикл был прерван с помощью break
, блок else
не выполнится. Это позволяет, например, выполнить определенный код в конце цикла, если цикл не был прерван.for i in range(5):
if i == 3:
print("Цикл прерван на итерации:", i)
break
else:
print("Цикл завершился без прерываний")
В этом цикле блок кода после
else
не выполнится. Но следующий цикл "переживет" все итерации и блок else
выполнится:for i in range(5):
print("Текущая итерация:", i)
else:
print("Цикл завершился без прерываний")
———
Good coding
#python #else #for #while #short
Please open Telegram to view this post
VIEW IN TELEGRAM
Перевод и решение задачи посвящается прекрасной кошке Асе. На самом деле с коробками любит играть кот Арсений. Поэтому у Аси не нашлось фото с коробкой
Сложность для junior: 4 / 10
Задача с решением на русском здесь
* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.
———
Good coding
#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Задача: Кошка Ася играет с коробками
Сложность: 4 / 10 Оригинал: https://dmoj.ca/problem/ecoo18r1p1 Художница Даша покупает коробки для своих проектов, но ее кошка Ася играет с коробками перед тем, как Даша сможет их использовать. Условия и переменные Кошка играет с каждой коробкой T дней Если…
Открываем терминал в корне проекта и прописываем —
python -m venv venv
— Флаг -m используется для запуска venv как исполняемого модуля.
— Первое написание venv является командой, а второе можно заменить на удобное название, под которым будет хранится директория виртуального окружения.
— Проходим по пути settings - project:<your_project> - python Interpreter для открытия окна с настройками виртуального окружения
— Нажимаем справа сверху add Interpreter и выбираем add local Interpreter
— Настройте интерпретатор и нажмите OK. По сути в Base Interpreter просто выберите доступный интерпретатор и это все настройки
Что бы активировать окружение на windows введите
.\venv\Scripts\activate
, где venv название директории с виртуальным окружением.Для активации на mac и linux введите
source venv/bin/activate
Если вы используете git bash, то команда активации будет следующей —
source venv/Scripts/activate
Что бы отключить окружение введите
deactivate
———
Good coding
#python #memo #venv
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача о том, как программисты добывают себе одежду
Сложность для junior: 7 / 10
Задача с решением на русском здесь
* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.
———
Good coding
#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Задача: Большая стирка
Сложность: 7 / 10 Оригинал: https://dmoj.ca/problem/ecoo19r1p1 В течении года в стране проводятся разные мероприятия по программированию, которые может посетить любой желающий, проверить свои навыки, пообщаться с единомышленниками, а самое главное - выиграть…
Что может быть интересного в столь простой и уже не популярной игре, как крестики-нолики? Игра элементарна и наверное навсегда останется украшением школьных парт и полей тетрадей. Ну и какой программист не писал крестики нолики на этапе обучения?
Играя в карты можно быть уверенным, что каждая партия уникальна и никогда не повториться. А общее количество уникальных партий в крестики нолики, учитывающих победы и ничьи, составляет 26 830.
Довольно скромно
Недавно я прочитал книгу. Называется 'Математика с дурацкими рисунками'. Оттуда и узнал про интересную модификацию крестиков-ноликов.
Суть в том, что поле игры всё так же состоит из 9 квадратов, но теперь каждый квадрат является самостоятельным полем крестиков-ноликов размером 3x3. В итоге поле представляет собой 9 отдельных "классических" игр в крестики-нолики.
Как программисты мы можем представить такое поле в виде трехмерной матрицы:
game_board = [
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']],
[['.', '.', '.'], ['.', '.', '.'], ['.', '.', '.']]
]
Весь game play строится на том, что поле, в котором игрок будет делать ход, зависит от хода его соперника. Например: если первый игрок поставил X в центральную клетку одного из малых полей, то следующий игрок должен поставить свой O на центральное большуо поле.
Подробные правила читайте тут — тык
В классическом варианте игры, при должном терпении, мы могли бы сыграть 26 830 возможных уникальных партий и сказать, что мы видели всё и нам скучно. Но в мега варианте такой роскоши себе позволить нельзя. Здесь мы получаем приморно 10^30 уникальных партий. Это вот такое число 1000000000000000000000000000000, которое называется нониллион. Даже если прожить 100 лет и каждую секунду играть уникальную партию, нам не удастся перебрать даже 1% возможных вариантов.
Меня всё это увлекло и я попробовал написать игру. Как сказано выше, здесь мы имеем дело с трехмерной матрицей, но при этом не имеем никакой сложной навигации, что даёт возможность для практики новичкам.
Игру можно посмотреть в репазитории.
Если кому то будет интересно, можно дописать к ней интерфейс. Сейчас весь game play осуществляется только через консоль.
Буду рад комментариям, оценкам, критике и исправлениям.
Также ссылка на вдохновившую меня книгу — Математика с дурацкими рисунками
———
Good coding
#python #list #matrix #game #offtop
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Правила игры: Мега крестики нолики
Игровое поле: Поле состоит из 9 больших квадратов (игровых досок), каждая из которых является самостоятельным полем крестиков-ноликов размером 3x3. В итоге поле представляет собой 9 отдельных "классических" игр в крестики-нолики. Очередность ходов: Как и…
Представьте что вы попали на необитаемый остров. Чем бы занялись? Можно добыть еды или обустроить жилище, а можно как наш герой наблюдать за приливами и отливами
Сложность для junior: 5 / 10
Задача с решением на русском здесь
* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.
———
Good coding
#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Задача: Приливы
Сложность: 5 / 10 Оригинал: https://dmoj.ca/problem/dmopc14c7p2 Туко застрял на острове. Преодолевая скуку он начал находить обычные вещи довольно увлекательными. Туко стал наблюдать за поведением океана и заметил, что в разное время суток уровень воды то…
🔥3
Циклический сдвиг — это когда каждая итерация цикла перемещает первый элемент списка в конец, а все остальные элементы сдвигает на минус один индекс. Есть два способа сделать это.
С созданием копии списка:
my_list = [1, 5, 2, 4, 3]
new_list = my_list[:]
for i in range(len(my_list)):
my_list = new_list[i:] + new_list[:i]
Без копии:
my_list = [1, 5, 2, 4, 3]
for _ in range(len(my_list)):
my_list.append(my_list[0])
my_list.pop(0)
Выбор способа зависит от задачи.
———
Good coding
#python #short #list
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Помните такие конструкции в детских играх или в каких-то туториалах, когда нужно соединить линией элементы, которые подходят друг другу по каким-либо свойствам? Например в левом столбике названия цветов, а в правом их обозначения. Скорее всего, некоторые линии объединенных элементов будут пересекаться. На основании этого описания, представим два списка:
a = [5, 4, 1, 3, 2]
b = [1, 3, 2, 5, 4]
Соедините мысленно все одинаковые числа линиями. Как с помощью python посчитать количество пересечений?
Рассмотрим функцию
find_intersections
def find_intersections(left_side, right_side):
num_fields = len(left_side)
intersections = 0
right_indices = {right_side[i]: i for i in range(num_fields)}
for i in range(num_fields):
for j in range(i + 1, num_fields):
left_cow_a = left_side[i]
left_cow_b = left_side[j]
right_cow_a = right_indices[left_cow_a]
right_cow_b = right_indices[left_cow_b]
if right_cow_a > right_cow_b:
intersections += 1
return intersections
Функция
find_intersections
подсчитывает количество "пересечений" между элементами двух списков — left_side
и right_side
.Пересечение — это такая ситуация, когда два элемента в одном списке расположены в одном порядке, а в другом — в обратном.
1. Инициализация переменных:
•
num_fields
— количество элементов в списках (они одинаковой длины).•
intersections
— счетчик пересечений, инициализируется нулем.2. Создание словаря индексов:
•
right_indices
— это словарь, где каждому элементу из списка right_side
сопоставляется его индекс. Это нужно, чтобы быстро находить позиции элементов из right_side
.3. Два вложенных цикла для перебора пар элементов:
• Внешний цикл (
for i in range(num_fields)
) перебирает каждый элемент списка left_side
как первый элемент пары.• Внутренний цикл (
for j in range(i + 1, num_fields)
) перебирает каждый следующий элемент списка как второй элемент пары.4. Сравнение порядков элементов в списках:
• Для текущей пары элементов
left_cow_a
(из left_side[i]
) и left_cow_b
(из left_side[j]
), находятся их индексы в right_side
с помощью словаря right_indices
: это right_cow_a
и right_cow_b
.• Если в
right_side
первый элемент пары (right_cow_a
) находится позже второго (right_cow_b
), то это пересечение, и счетчик intersections
увеличивается на 1.5. Результат:
• Функция возвращает общее количество пересечений.
Пример: Если:
•
left_side = [1, 2, 3]
•
right_side = [2, 1, 3]
• То пересечение будет между 1 и 2, так как их порядок в
right_side
обратен порядку в left_side
.———
Good coding
#python #info #list #matrix #algorithm
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2 1 1
Если для хранения данных не требуется сохранения порядка и дубликатов элементов, можно использовать множества вместо списков. Чем длиннее список элементов и чем дальше элемент поиска, тем больше преимуществ у множества.
Давайте убедимся на деле:
import time, random
# Генерируем список с дубликатами и преобразуем в множество
numbers_list = [random.randint(0, 10**6) for _ in range(10**6)]
numbers_set = set(numbers_list)
# Список случайных элементов для поиска
search_items = random.sample(range(10**6), 1000)
# Функция для замера времени поиска
def measure_search(container):
start = time.time()
for item in search_items:
item in container
return time.time() - start
# Замеры времени поиска
list_time = measure_search(numbers_list)
set_time = measure_search(numbers_set)
# Результаты
print(f"Поиск в списке: {list_time:.6f} сек") # Примерно 4.3 сек
print(f"Поиск в множестве: {set_time:.6f} сек") # Примерно 0.0009 сек
———
Good coding
#python #short #list #set
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2 1
Предположим, что наше приложение — это что-то там связанное с английским. У нас есть некоторый словарь в котором ключ — это английское слово, а значение — перевод этого слова:
animals = {
'cat': 'кот',
'dog': 'собака',
'mouse': 'мышь',
'elephant': 'слон',
}
Нам нужно чтобы было наоборот: ключи на русском, а значения на английском. Пишем простое выражение:
print({value: key for key, value in animals.items()})
# >>> {'кот': 'cat', 'собака': 'dog', 'мышь': 'mouse', 'слон': 'elephant'}
———
Good coding
#python #short #dict
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Допустим вам для проекта нужно сгенерировать английский алфавит.
alphabet = {chr(i): i - 64 for i in range(65, 91)}
Эта строчка генерирует словарь с прописными буквами английского алфавита.
Функция chr() конвертирует целое число в Unicode-символ и возвращает его.
Юникод и кодировки в Python
———
Good coding
#python #short #dict #unicode
Please open Telegram to view this post
VIEW IN TELEGRAM
Ravesli
Функция chr() в Python / Ravesli
❤2👍1 1
С помощью метода reverse()
my_position = ['first', 'second', 'third']
my_position.reverse()
print(my_position)
# >>> ['third', 'second', 'first']
С помощью функции reversed()
sequence = [1, 2, 3, 4, 5, 6]
reverse_sequence = list(reversed(sequence))
print(reverse_sequence)
# >>> [6, 5, 4, 3, 2, 1]
С помощью среза
split_name = ['r', 'd', 'n', 'a', 's', 'k', 'e', 'l', 'a']
reverse_split_name = split_name[::-1]
print(reverse_split_name)
# >>> ['a', 'l', 'e', 'k', 's', 'a', 'n', 'd', 'r']
———
Good coding
#python #short #list
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2 1
Класс
deque
(от "double-ended queue" - двухсторонняя очередь) в Python удобен для работы с коллекцией элементов, где важны операции добавления и удаления элементов в начале и в конце списка. Обычные списки делают это медленно, так как элементы приходится смещать, а deque
оптимизирован под такие операции, выполняя их за O(1).from collections import deque
# Создаем deque и добавляем элементы
queue = deque([1, 2, 3])
queue.append(4) # добавляет 4 в конец
queue.appendleft(0) # добавляет 0 в начало
print(queue) # deque([0, 1, 2, 3, 4])
# Удаляем элементы
queue.pop() # удаляет последний элемент
queue.popleft() # удаляет первый элемент
print(queue) # deque([1, 2, 3])
———
Good coding
#python #short #list #libraries #deque #collections
Please open Telegram to view this post
VIEW IN TELEGRAM
Я славно поработал и написал 2 статьи посвященные алгоритму BFS (поиск в ширину) и алгоритму Дейкстры (поиск во взвешенных графах). Для меня лучший способ в чем то разобраться - это объяснить другим как это работает. Эти работы не исключение.
Краткая статистика
- 25 000 символов
- 3 600 слов
- 23 часа работы
———
Первая часть - Алгоритмы поиска путей на пальцах. Часть 1: Поиск в ширину
Первая часть - Алгоритмы поиска путей на пальцах. Часть 2: Алгоритм Дейкстры
———
Это всё что я использовал для написания материала и создания анимаций:
1. Алгоритмика — много материала об алгоритмах
2. Clippa — здесь можно доработать гифки
3. ChatGPT — все знают
4. Program4you — здесь можно создавать и анимировать графы
5. Теория графов — хороший материал для прочной базы
6. Двусторонняя очередь — статья о классе deque
7. Кучи и приоритетные очереди — статья о модуле heapq
———
Good coding
#python #info #algorithms #dijkstra #bfs #graphs #habr #articles
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Алгоритмы поиска путей на пальцах. Часть 1: Поиск в ширину
Давайте представим, что вы устроились много лет назад в 2GIS и вам выпала честь написать алгоритм, который будет прокладывать самый короткий автомобильный маршрут от точки A к точке B. Вы...