🌷Всех дам поздравляю с Международным женским днем! 🌷
Желаю вам счастья, любви, здоровья, отличного настроения, улыбок, солнца на улице и в душе!
Мы вас очень любим и ценим!
[код]
Желаю вам счастья, любви, здоровья, отличного настроения, улыбок, солнца на улице и в душе!
Мы вас очень любим и ценим!
[код]
Решение предыдущей задачи
Если кратко, то при поиске словарь проверяет сначала хэш (hash) от ключей. Разные хэши – разные ключи – разные записи. Если хэши равны, то проверяется простое равенство (==) ключей. Если и они равны, то считается, что это один и тот же ключ, и ему отвечает одна и та же запись в словаре.
Все
Кстати, спрашивали, как добраться до этих nan. Вот так:
Теперь ситуация с ключами
Поэтому для словаря – ключи
Таким образом, у нас будет 2 записи от двух nan, и одна запись от
Если кратко, то при поиске словарь проверяет сначала хэш (hash) от ключей. Разные хэши – разные ключи – разные записи. Если хэши равны, то проверяется простое равенство (==) ключей. Если и они равны, то считается, что это один и тот же ключ, и ему отвечает одна и та же запись в словаре.
Все
float('nan') имеют одинаковый хэши, но значение NaN (not a number – не число), не равно никакому другому float, включая само себя и другие float('nan'), поэтому для словаря все nan – разные ключи, и каждому из них отвечает отдельная запись.>>> float('nan') == float('nan')
False
>>> hash(float('nan'))
0
>>> {float('nan'): 1, float('nan'): 2}
{nan: 1, nan: 2}Кстати, спрашивали, как добраться до этих nan. Вот так:
>>> keys = list(d.keys()) # список ключей
>>> d[keys[0]], d[keys[1]] # по ключам добираемся до значений
(1, 2)
>>> del d[keys[0]] # убрать одноТеперь ситуация с ключами
1, 1.0, True. Оказывается, их хэши тоже равны между собой. Нюанс в том, что и сами они равны между собой!>>> hash(1), hash(1.0), hash(True)
(1, 1, 1)
>>> 1 == 1.0 == True
TrueПоэтому для словаря – ключи
1, 1.0, True – одинаковые и дают доступ к одной и той же записи. Фактический ключ будет тот, что был записан самым первым.Таким образом, у нас будет 2 записи от двух nan, и одна запись от
1, 1.0, True. Итого, ответ – 3.Танчики на PyGame
Занятые вышли дни, поэтому не смог написать новых статей. Но, чтобы вы не скучали, вот вам один из моих проектов – Танчики на PyGame.
Игра хоть и не доделана полностью: в ней нет меню, звуков и редактора, но геймплей вполне работоспособный. Танчики спавнятся, атакуют, взрываются, стены разрушаются.
Управление – стрелки и пробел на выстрел.
Возможно, кому-то код пригодится, как учебное пособие, или вдруг найдутся добровольцы, которые внесут в него свой вклад. Ссылка на GitHub.
Занятые вышли дни, поэтому не смог написать новых статей. Но, чтобы вы не скучали, вот вам один из моих проектов – Танчики на PyGame.
Игра хоть и не доделана полностью: в ней нет меню, звуков и редактора, но геймплей вполне работоспособный. Танчики спавнятся, атакуют, взрываются, стены разрушаются.
Управление – стрелки и пробел на выстрел.
main.py – точка входа. Инициализирует PyGame, создает класс Game, обрабатывает ввод с клавиатуры.ai.py – интеллект врагов, включая алгоритм их появления.bonus.py – игровой объект бонуса.bonus_field_protect.py – алгоритм работы бонуса на защиту базы.config.py – конфигурация и ключи запуска.discrete_map.py – объект дискретной 2D карты (нужна для карты поля боя и карты для столкновений).explosion.py – игровой объект взрыва.field.py – игровой объект поля боя, обрабатывает столкновения и разрушение мира.game.py – собирает все объекты вместе и связывает события.my_base.py – игровой объект базы игрока (орел).projectile.py – игровой объект снаряда.score_node.py – игровой объект очков при уничтожении врага.spritesheet.py – загрузчик спрайтов из одной сборной текстуры.tank.py – игровой объект любого танка (своего или вражеского).ui.py – элементы пользовательского интерфейса.util.py – вспомогательные функции и классы, включая аниматор, таймер и базовый игровой объект.Возможно, кому-то код пригодится, как учебное пособие, или вдруг найдутся добровольцы, которые внесут в него свой вклад. Ссылка на GitHub.
Думаю, вы знаете, что при форматировании можно задавать параметры, например, число знаков для дробных чисел или выравнивание текста:
Эти параметры тоже можно задать динамически. Нет нужды дважды вызывать
Также вы без проблем можете получать доступ к элементам списков, словарей или объектов прямо внутри форматных строк:
С богатыми возможностями форматирования вы можете познакомиться на сайте https://pyformat.info/ (англ.)
От себя еще добавлю, что f-строки еще круче, чем
Главное условие, чтобы это выражение допускало обертывание в круглые скобки, поэтому нельзя вот так:
Вообще, способность вычислять выражения внутри строк и подставлять результат в нужно место строки называется: "интерполяция строк". Она работает не зависимо от типа кавычек строки, главно наличии буквы f перед строкой.
>>> '{:.3}'.format(2.7182)
'2.72'
>>> '{:^15}'.format('hello')
' hello 'Эти параметры тоже можно задать динамически. Нет нужды дважды вызывать
format, а достаточно просто добавить фигурные скобки внутрь фигурных скобок:>>> '{:.{prec}}'.format(2.7182, prec=3)
'2.72'
>>> '{:{align}{width}}'.format('hello', align='^', width=15)
' hello 'Также вы без проблем можете получать доступ к элементам списков, словарей или объектов прямо внутри форматных строк:
data = [4, 8, 15, 16, 23, 42]
'{d[4]} {d[5]}'.format(d=data)
# '23 42'
class Plant(object):
type = 'tree'
'{p.type}'.format(p=Plant())С богатыми возможностями форматирования вы можете познакомиться на сайте https://pyformat.info/ (англ.)
От себя еще добавлю, что f-строки еще круче, чем
''.format(...): внутри фигурных скобок возможно поставить вообще любое валидное Python выражение, хоть вызов функций:>>> f'2 + 2 = {2 + 2}'
'2 + 2 = 4'
>>> f'sqrt(2) = {2**0.5:.5}'
'sqrt(2) = 1.4142'
>>> data = [1, 2, 3, 4]
>>> f'data sum = {sum(data)}'
'data sum = 10'Главное условие, чтобы это выражение допускало обертывание в круглые скобки, поэтому нельзя вот так:
>>> f'{import os}'
File "<fstring>", line 1
(import os)
^
SyntaxError: invalid syntaxВообще, способность вычислять выражения внутри строк и подставлять результат в нужно место строки называется: "интерполяция строк". Она работает не зависимо от типа кавычек строки, главно наличии буквы f перед строкой.
📕 #Библиотека XlsxWriter
Белые воротнички не умеют читать файлы JSON? Начальник требует от вас выгружать отчеты в ламповой Эксельке? Не беда. Библиотека XlsxWriter поможет все автоматизировать без головной боли. Просто взгляните на код:
В статье больше примеров!
#xls #excel
Белые воротнички не умеют читать файлы JSON? Начальник требует от вас выгружать отчеты в ламповой Эксельке? Не беда. Библиотека XlsxWriter поможет все автоматизировать без головной боли. Просто взгляните на код:
import xlsxwriter
# откроем файл на запись
workbook = xlsxwriter.Workbook('my_report.xlsx')
# создадим лист
worksheet = workbook.add_worksheet()
# данные
expenses = (
['Аренда', 1000],
['Комуналка', 100],
['Еда', 300],
['Качалка', 50],
)
# формат для денег
money = workbook.add_format({'num_format': '#,##0"₽"'})
# формат жирности шрифта
bold = workbook.add_format({'bold': True})
worksheet.write('A1', 'Наименование', bold)
worksheet.write('B1', 'Потрачено', bold)
for i, (item, cost) in enumerate(expenses, start=2):
worksheet.write(f'A{i}', item)
worksheet.write(f'B{i}', cost, money)
# колонкой ниже добавить подсчет суммы
worksheet.write('A6', 'Итого:', bold)
worksheet.write('B6', '=SUM(B2:B5)', money)
# задать колонкам от 0 до 1 каждой ширину 15
worksheet.set_column(0, 1, 15)
# сохраняем и закрываем
workbook.close()В статье больше примеров!
#xls #excel
tirinox.ru
Пишем файл Excel из Python
Если вдруг вам потребуется, к примеру, выгружать отчеты из вашей программы, почему бы не воспользоваться общепринятым офисным форматом – Excel? В этом нет ничего сложного, потому что есть прекрасная библиотека XlsxWriter. Приведу для вас немного примеров…
Python – это компилятор или интерпретатор?
Ответ неоднозначный. Python – это и первое, и второе. (Здесь мы говорим про самый распространенный CPython)
Когда вы вводите в терминале операторы по одному, то они выполняются сразу после ввода, в этом случае Python играет роль интерпретатора.
А если вы скармливаете Python исходный файл целиком, то он сначала компилирует его в промежуточное представление: низкоуровненый байт-код. Замечали файлы
Набросал для вас реализацию языка Brainfuck, причем в двух вариантах: интерпретатора и компилятора. Интерпретатор читает программу и сразу выполняет ее команда за командой, а компилятор выдает нам исполняемый файл, которым мы запускаем отдельно от компилятора. Уловили разницу?
Ответ неоднозначный. Python – это и первое, и второе. (Здесь мы говорим про самый распространенный CPython)
Когда вы вводите в терминале операторы по одному, то они выполняются сразу после ввода, в этом случае Python играет роль интерпретатора.
А если вы скармливаете Python исходный файл целиком, то он сначала компилирует его в промежуточное представление: низкоуровненый байт-код. Замечали файлы
*.pyc? Вот это уже скомпилированный байт-код. Он выполняется виртуальной машиной Python.Набросал для вас реализацию языка Brainfuck, причем в двух вариантах: интерпретатора и компилятора. Интерпретатор читает программу и сразу выполняет ее команда за командой, а компилятор выдает нам исполняемый файл, которым мы запускаем отдельно от компилятора. Уловили разницу?
tirinox.ru
Пишем Brainfuck на Python
Есть мнение, что каждый программист должен написать в жизни хотя бы один язык программирования, либо реализовать уже существующий, но своими руками. В качестве примера мы начнем с самого простого и создадим Brainfuck. Согласно Вики: Brainfuck — один из и…
Рассказ о том, как я автоматизировал загрузку гербов субъектов РФ из Википедии как небольшой туториал по веб-скрейпингу.
tirinox.ru
Парсим Википедию с Beautiful Soup 4
Для одного из моих проектов понадобилось раздобыть список субъектов РФ с их гербами. Я решил автоматизировать этот процесс, написав скрипт на языке Python. Поделюсь с вами процессом разработки, трудностями, с которыми столкнулся и их решениями. Парсить будем…
Разбор URL
Функция urlparse из модуля urllib.parse разбирает URL на составные части: протокол, имя хоста, порт, путь, запрос и прочие.
Имя хоста, порт, логин и пароль объединены в поле netloc, но их компоненты доступны для чтения по этим атрибутам:
Собрать обратно ParseResult в URL:
Если мы хотим в URL поменять какие-то части, удобно делать вот так:
Однако таким способом нельзя поменять компоненты netloc, например, отдельно порт. netloc нужно менять целиком:
Функция urlparse из модуля urllib.parse разбирает URL на составные части: протокол, имя хоста, порт, путь, запрос и прочие.
>>> u1 = urlparse('https://tirinox:1234@www.site.com:8080/some/page/index.html?page=2&action=login')
>>> u1
ParseResult(scheme='https', netloc='tirinox:1234@www.site.com:8080', path='/some/page/index.html', params='', query='page=2&action=login', fragment='')
>>> u1.scheme, u1.query, u1.netloc
('https', 'page=2&action=login', 'tirinox:1234@www.site.com:8080')Имя хоста, порт, логин и пароль объединены в поле netloc, но их компоненты доступны для чтения по этим атрибутам:
>>> u1.username, u1.password, u1.hostname, u1.port
('tirinox', '1234', 'www.site.com', 8080)Собрать обратно ParseResult в URL:
>>> u1.geturl()
'https://www.site.com:8080/some/page/index.html?page=2&action=login'Если мы хотим в URL поменять какие-то части, удобно делать вот так:
>>> u1._replace(scheme='http').geturl()
'http://www.site.com:8080/some/page/index.html?page=2&action=login'
Однако таким способом нельзя поменять компоненты netloc, например, отдельно порт. netloc нужно менять целиком:
>>> u1._replace(netloc="user:password@www.site.com:8090").geturl()
'https://user:password@www.site.com:8090/some/page/index.html?page=2&action=login'globals(), locals(), vars(), dir()
Программист на Python может узнать, какие именно переменные определенны в данный момент в интерпретаторе. Переменные можно разделить на локальные и глобальные. Глобальные определены на верхнем уровне кода снаружи функций и классов (грубо говоря без отступов слева). Локальные переменные наоборот определены внутри своих зон видимости, ограниченных классами и функциями.
Функция globals() выдает словарь глобальных переменных (ключ – имя переменной). Функция locals() возвращает словарь только локальных переменных. Пример:
Обратите внимание, что переменная y в locals() имеет другое значение, нежели чем в globals(). Это две разные переменные из разных областей, но внутри функции приоритет имеет локальная y.
Еще важно знать, что в список переменных входят не только простые переменные, которые вы определяете через знак присваивания, но и функции, классы и импортированные модули!
Через словари из locals() и globals() переменные можно не только читать, но и создавать, перезаписывать и удалять:
Функция vars() ведет себя как locals(), если вызвана без аргумента, а если с аргументом, то она просто получает
В глобальном контексте все три функции возвращают одно и тоже – глобальные переменные. Проверьте:
Функциия dir(), будучи вызвана без параметра, возвращает список имен переменных. Глобальных или локальных в зависимости от места вызова:
Все рассмотренные выше функции являются встроенными и не требуют импортов.
Программист на Python может узнать, какие именно переменные определенны в данный момент в интерпретаторе. Переменные можно разделить на локальные и глобальные. Глобальные определены на верхнем уровне кода снаружи функций и классов (грубо говоря без отступов слева). Локальные переменные наоборот определены внутри своих зон видимости, ограниченных классами и функциями.
Функция globals() выдает словарь глобальных переменных (ключ – имя переменной). Функция locals() возвращает словарь только локальных переменных. Пример:
x, y = 5, 10
def test():
y, z = 33, 44
print('globals:', globals())
print('locals:', locals())
test()
"""Вывод:
globals: {'__name__': '__main__', ... '__file__': '/Users/.../vars.py', '__cached__': None, 'x': 5, 'y': 10, 'test': <function test at 0x107677280>}
locals: {'y': 33, 'z': 44}"""Обратите внимание, что переменная y в locals() имеет другое значение, нежели чем в globals(). Это две разные переменные из разных областей, но внутри функции приоритет имеет локальная y.
Еще важно знать, что в список переменных входят не только простые переменные, которые вы определяете через знак присваивания, но и функции, классы и импортированные модули!
Через словари из locals() и globals() переменные можно не только читать, но и создавать, перезаписывать и удалять:
>>> x = 10
>>> globals()['x'] = 5
>>> x
5
>>> globals()['new_var'] = 10
>>> new_var
10
>>> del globals()['new_var']
>>> new_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'new_var' is not definedФункция vars() ведет себя как locals(), если вызвана без аргумента, а если с аргументом, то она просто получает
_ _ dict _ _ от аргумента. Если его нет у аргумента, то будет TypeError.class Foo:
def __init__(self):
self.x = 5
f = Foo()
print(vars(f)) # {'x': 5}
print(vars(f) == f.__dict__) # TrueВ глобальном контексте все три функции возвращают одно и тоже – глобальные переменные. Проверьте:
print(globals())
print(locals())
print(vars())
print(globals() == locals() == vars()) # TrueФункциия dir(), будучи вызвана без параметра, возвращает список имен переменных. Глобальных или локальных в зависимости от места вызова:
def test():
x = 10
print(dir()) # ['x']
y = 10
test()
print(dir()) # ['__annotations__', ..., '__spec__', 'test', 'y']Все рассмотренные выше функции являются встроенными и не требуют импортов.
В дополнение об областях видимости переменных
В отличие он некоторых других языков в Python блоки типа
Частая ошибка – затирание внешней переменной в цикле for:
Зоны видимости отделяются только функциями, классами и модулями. Здесь все переменные x – разные:
Самая широкая зона видимости называется builtin. В нее попадают все имена, известные интерпретатору в данный момент, включая вещи импортированные из других модулей.
Казалось бы мы затерли pi, но мы затерли его лишь в глобальной области видимости. Повторно импортируя pi, мы получаем старую переменную с тем же адресом, иными словами мы достаем ее из builtin области в global.
Вы знали о всех этих особенностях?
В отличие он некоторых других языков в Python блоки типа
for, if, while, with не создают областей видимости (scope) для переменных, то есть переменная внутри и снаружи блока будет одна и та же:x = 1
if True:
x = 2
print(x) # 2Частая ошибка – затирание внешней переменной в цикле for:
i = 10
for i in range(5): # затирает i
...
print(i) # 4Зоны видимости отделяются только функциями, классами и модулями. Здесь все переменные x – разные:
x = 1
class Foo:
x = 2
def method(self):
x = 3
return x
print(x, Foo.x, Foo().method()) # все 3 разныеСамая широкая зона видимости называется builtin. В нее попадают все имена, известные интерпретатору в данный момент, включая вещи импортированные из других модулей.
>>> from math import pi
>>> pi, id(pi)
(3.141592653589793, 4465320624)
>>> pi = 3
>>> pi, id(pi)
(3, 4462262880)
>>> from math import pi
>>> pi, id(pi)
(3.141592653589793, 4465320624)Казалось бы мы затерли pi, но мы затерли его лишь в глобальной области видимости. Повторно импортируя pi, мы получаем старую переменную с тем же адресом, иными словами мы достаем ее из builtin области в global.
Вы знали о всех этих особенностях?
Зачем мне вообще нужны комплексные числа? – спросят многие из вас.
Но разве не круто извлечь корень из -1?
А вы посмотрите на этот классный синтаксис:
Самое чудесное, что простыми формулами на комплексных числах можно описывать бесконечно самоподобные структуры, например, множество Мандельброта.
Заинтересованы?
Но разве не круто извлечь корень из -1?
А вы посмотрите на этот классный синтаксис:
>>> 1 + 2j
(1+2j)
>>> type(1 + 2j)
<class 'complex'>Самое чудесное, что простыми формулами на комплексных числах можно описывать бесконечно самоподобные структуры, например, множество Мандельброта.
c = x + 1j * y
z = 0j
for n in range(iters):
z = z ** 2 + c
if (z * z.conjugate()).real > 4.0:
break
img.putpixel((px, py), palette[n])Заинтересованы?
tirinox.ru
Комплексные числа в Python. Бонус: фрактал
В Python есть встроенный тип данных complex, который моделируют комплексные числа. По-моему, теория комплексных чисел – настоящий прорыв в математике, оказавший колоссальное влияние на современную физику. Неудивительно, что комплексные числа оказались в стандартной…
Что если нужно импортировать модули не из директории проекта и не те, что установлены через pip, а из произвольного места на диске?
Конечно, можно было бы скопировать код оттуда в своей проект, но так не рекомендуется делать. Есть и другие решения.
В модуле sys есть переменная path. Она содержит список путей, в которых Python ищет названия модулей для импорта. Пожалуйста, не путайте
Мы можем влиять на эту переменную, например, добавляя туда свои пути. Если добавить в начало списка, то поиск модулей начнется именно с нового пути.
Порядок операторов здесь важен. Нельзя сделать сначала import, потому что на момент импорта my_module система еще не знает, где его можно найти.
Функция
Также, набрав команду
Минус способов с добавлением путей через
PYTHONPATH – переменная окружения, которую вы можете установить перед запуском интерпретатора. Будучи заданной, она также влияет на sys.path, добавляя пути поиска модулей в начало списка.
На Windows можно использовать команду set. Если надо задать два и более путей, разделите их точкой с запятой:
На Linux и macOS можно использовать export. Два и более путей разделяются двоеточием:
Или даже в одну строку:
Кто не знал, ключ
Если вам заранее известны пути импорта дополнительных модулей, можно задать их прямо в IDE. На примере PyCharm, заходите в настройки: Project: ваш проект – Project Structure – Add Content Root.
Таким образом, у вас будут работать все фишки IDE для импортированных по сторонним путям модулей, но код будет запускаться корректно только из этой IDE, а чтобы запустить его из-вне, например из терминала, придется все равно прописать PYTHONPATH.
Конечно, можно было бы скопировать код оттуда в своей проект, но так не рекомендуется делать. Есть и другие решения.
В модуле sys есть переменная path. Она содержит список путей, в которых Python ищет названия модулей для импорта. Пожалуйста, не путайте
sys.path и переменную окружения PATH (которая, кстати, доступна через os.environ['PATH']). Это разные вещи, последняя не имеет отношения к поиску модулей Python.>>> import sys
>>> sys.path
['', '/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python38.zip', ..., '/usr/local/lib/python3.8/site-packages']
Мы можем влиять на эту переменную, например, добавляя туда свои пути. Если добавить в начало списка, то поиск модулей начнется именно с нового пути.
import sys
sys.path.insert(0, '/Users/you/Projects/my_py_lib')
import my_module # этот модуль лежит в my_py_libПорядок операторов здесь важен. Нельзя сделать сначала import, потому что на момент импорта my_module система еще не знает, где его можно найти.
import sys
import my_module # ModuleNotFoundError
sys.path.insert(0, '/Users/you/Projects/my_py_lib') # поздно
Функция
site.addsitedir тоже модифицирует sys.path, добавляя путь в конец списка. Еще она делает некоторые дополнительные вещи, но мы их не касаемся. Пример использования:import site
site.addsitedir('/Users/you/Projects/my_py_lib')
import my_moduleТакже, набрав команду
python3 -m site в командной строке, вы можете узнать пути для импорта в текущим интерпретаторе Python.Минус способов с добавлением путей через
sys.path и site – IDE скорее всего не будет видеть и индексировать эти динамические пути, а значит будет много красных подчеркиваний и отсутствие автодополнения, даже если код при этом прекрасно выполняется.PYTHONPATH – переменная окружения, которую вы можете установить перед запуском интерпретатора. Будучи заданной, она также влияет на sys.path, добавляя пути поиска модулей в начало списка.
На Windows можно использовать команду set. Если надо задать два и более путей, разделите их точкой с запятой:
set PYTHONPATH=C:\pypath1\;C:\pypath2\
python -c "import sys; print(sys.path)"
# Пример вывода:
['', 'C:\\pypath1', 'C:\\pypath2', 'C:\\opt\\Python36\\python36.zip', 'C:\\opt\\Python36\\DLLs', 'C:\\opt\\Python36\\lib', 'C:\\opt\\Python36', ..., 'Python36\\lib\\site-packages\\Pythonwin']На Linux и macOS можно использовать export. Два и более путей разделяются двоеточием:
export PYTHONPATH='/some/extra/path:/foooo'
python3 -c "import sys; print(sys.path)"
# Пример вывода
['', '/some/extra/path', '/foooo', ...]Или даже в одну строку:
PYTHONPATH='/some/path' python3 -c "import sys; print(sys.path)"Кто не знал, ключ
-c для python3 просто выполняет строчку кода. И да, лишних пробелов вокруг знака равно не должно быть, это такой синтаксис.Если вам заранее известны пути импорта дополнительных модулей, можно задать их прямо в IDE. На примере PyCharm, заходите в настройки: Project: ваш проект – Project Structure – Add Content Root.
Таким образом, у вас будут работать все фишки IDE для импортированных по сторонним путям модулей, но код будет запускаться корректно только из этой IDE, а чтобы запустить его из-вне, например из терминала, придется все равно прописать PYTHONPATH.
Знаю, давно ничего для вас не писал. Но я исправляюсь.
tirinox.ru
Расстояние Левенштейна на Python
Как понять насколько близки две строки? Как поисковая система все равно находит то, что надо, даже если вы совершили пару опечаток в запросе? В этом вопросе нам поможет расстояние по Левенштейну или редакционное расстояние. Почему редакционное? Потому что…
Левенштейн на практике, это, например, нечеткое сравнение строк:
Или нечеткий поиск текста:
Интересно? Тогда читайте новую заметку.
>>> from fuzzywuzz import fuzz
>>> fuzz.token_sort_ratio("я люблю спать", "Я люблю спать!")
100
>>> fuzz.token_sort_ratio("я люблю спать", "я люблю есть")
56Или нечеткий поиск текста:
from fuzzywuzzy import process
strings = ['привет', 'здравствуйте', 'приветствую', 'хай', 'здорова', 'ку-ку']
process.extract("Прив", strings, limit=3)
# [('привет', 90), ('приветствую', 90), ('здравствуйте', 45)]Интересно? Тогда читайте новую заметку.
tirinox.ru
Нечеткое сравнение текстов на Python с FuzzyWuzzy
Недавно мы обсуждали расчет расстояния Левеншейна, настало время испытать его применение на практике. Библиотека FuzzyWuzzy содержит набор функций для нечеткого поиска строк, дедупликации (удаления копий), корректировки ошибок. Она позволяет стать поиску…
Задачка. Есть глобальная переменная
g. В функции мы делаем del g. g = 100
def f():
global g
g = 200
del g
g = 300
f()
print(g)Что будет выведено на экран pring(g)?
Anonymous Quiz
17%
100
5%
200
47%
300
31%
NameError (удалили же g)
Инструкция del (от англ. delete), как можно понять из названия, нужна чтобы что-то удалять, а именно имена переменных, атрибуты объектов, элементы списков и ключи словарей.
1. Удаление элемента из списка по индексу:
Также можно удалять по срезам. Пример: удаление первых двух элементов:
Удаление последних n элементов:
Удаление элементов с четными индексами:
Удаление произвольного среза:
Не путайте
2. Удаление ключа из словаря. Просто:
А вот строки, байты и сеты del не поддерживают.
3. Удаление атрибута объекта.
Примечание: можно через del удалить метод у самого класса (
4. Что значит удалить имя переменной? Это просто значит, что надо отвязать имя от объекта (при этом если на объект никто более не ссылается, то он будет освобожден сборщиком мусора), а само имя станет свободно. При попытке доступа к этому имени после удаления будет
Здесь кроется один нюанс. Если переменная была внутри функции помечена, как
Чтобы реально удалить глобальную переменную, можно сделать так:
В пунктах 1, 2, 3 в качестве имен могут фигурировать выражения и ссылки, так как операции идут над содержимым объектов, а в пункте 4 должно быть строго формальное имя удаляемого объекта.
1. Удаление элемента из списка по индексу:
>>> x = [1, 2, 3, 4, 5]
>>> del x[2]
>>> x
[1, 2, 4, 5]Также можно удалять по срезам. Пример: удаление первых двух элементов:
>>> x = [1, 2, 3, 4, 5]
>>> del x[:2]
>>> x
[3, 4, 5]Удаление последних n элементов:
del x[n:].Удаление элементов с четными индексами:
del x[::2], нечетными: del x[1::2].Удаление произвольного среза:
del x[i:j:k].Не путайте
del x[2] и x.remove(2). Первый удаляет по индексу (нумерация с 0), а второй по значению, то есть находит в списке первую двойку и удаляет ее.2. Удаление ключа из словаря. Просто:
>>> d = {"foo": 5, "bar": 8}
>>> del d["foo"]
>>> d
{'bar': 8}
А вот строки, байты и сеты del не поддерживают.
3. Удаление атрибута объекта.
class Foo:
def __init__(self):
self.var = 10
f = Foo()
del f.var
print(f.var) # ошибка! Примечание: можно через del удалить метод у самого класса (
del Foo.method), но нельзя удалить метод у экземпляра класса (del Foo().method - AttributeError).4. Что значит удалить имя переменной? Это просто значит, что надо отвязать имя от объекта (при этом если на объект никто более не ссылается, то он будет освобожден сборщиком мусора), а само имя станет свободно. При попытке доступа к этому имени после удаления будет
NameError, пока ему снова не будет что-то присвоено.>>> a = 5
>>> del a
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not definedЗдесь кроется один нюанс. Если переменная была внутри функции помечена, как
global, то после ее удаления глобальная переменная никуда не денется, а имя освободится лишь в зоне видимости функции. Причем если мы снова присвоим ей значение, то она опять окажется глобальной, т.е. del не очищает информацию о global!g = 100
def f():
global g
g = 200
del g # g останется вне фукции
g = 300 # таже самая глобальная g
f()
print(g) # 300Чтобы реально удалить глобальную переменную, можно сделать так:
del globals()['g'].В пунктах 1, 2, 3 в качестве имен могут фигурировать выражения и ссылки, так как операции идут над содержимым объектов, а в пункте 4 должно быть строго формальное имя удаляемого объекта.
>>> x = [1, 2, 3]
>>> y = x
>>> del y # удаляет именно y, но x остаетсяЕще одна особенность del – она может удалить несколько вещей за раз, если передать в нее кортеж или список объектов на удаление.
Пусть задан список из 5 элементов:
x, y, z = 10, 20, [1, 2, 3]
del x, y, z[2]
Пусть задан список из 5 элементов:
x = [1, 2, 3, 4, 5]
del x[2], x[4]