1
0
mirror of https://github.com/satwikkansal/wtfpython synced 2024-11-24 03:54:25 +01:00

Translate Minor ones example

This commit is contained in:
Vadim Nifadev 2024-04-24 17:00:05 +03:00
parent 9e2508ae6a
commit f71b997a45

View File

@ -3630,3 +3630,144 @@ def dict_size(o):
+ Небольшой совет, если вы стремитесь уменьшить занимаемый программой объем памяти: не удаляйте атрибуты экземпляров и обязательно инициализируйте все атрибуты в `__init__`!
---
### ▶ Минорное *
<!-- Example ID: f885cb82-f1e4-4daa-9ff3-972b14cb1324 --->
* `join()` - строковая операция вместо списочной. (может показаться неочевидным при первом использовании)
**💡 Объяснение:** Если `join()` - это строковый метод, то он может работать с любым итеруемыми объектами (список, кортеж, итераторы). Если бы это был списковый метод, то его пришлось бы реализовывать отдельно для каждого типа. Кроме того, нет особого смысла помещать метод, специфичный для строки, в общий API объекта `list`.
* Несколько странных, но семантически правильных утверждений:
+ `[] = ()` - семантически корректное утверждение (распаковка пустого `кортежа` в пустой `список`)
+ `'a'[0][0][0][0][0]` также является семантически корректным утверждением, поскольку в Python строки являются [последовательностями](https://docs.python.org/3/glossary.html#term-sequence)(итерируемыми объектами, поддерживающими доступ к элементам с использованием целочисленных индексов).
+ `3 --0-- 5 == 8` и `--5 == 5` - оба семантически корректные утверждения и имеют значение `True`.
* Учитывая, что `a` - это число, `++a` и `--a` являются корректными утверждениями Python, но ведут себя не так, как аналогичные утверждения в таких языках, как C, C++ или Java.
```py
>>> a = 5
>>> a
5
>>> ++a
5
>>> --a
5
```
**💡 Объяснение:**
+ В грамматике Python нет оператора `++`. На самом деле это два оператора `+`.
+ `++a` преобразуется в `+(+a)`, а затем в `a`. Аналогично для утверждения `--a`.
+ На [StackOverflow](https://stackoverflow.com/questions/3654830/why-are-there-no-and-operators-in-python) обсуждается обоснование отсутствия операторов инкремента и декремента в Python.
* Вы наверняка знаете об операторе Walrus в Python. Но слышали ли вы когда-нибудь об операторе *пространственного инкремента*?
```py
>>> a = 42
>>> a -=- 1
>>> a
43
```
Он используется как альтернативный оператор инкрементации, вместе с другим оператором
```py
>>> a +=+ 1
>>> a
>>> 44
```
**💡 Объяснение:** Этот розыгрыш взят из твита [Raymond Hettinger](https://twitter.com/raymondh/status/1131103570856632321?lang=en). На самом деле оператор захвата пространства - это просто неправильно отформатированное `a -= (-1)`. Что эквивалентно `a = a - (- 1)`. Аналогично для случая `a += (+ 1)`.
* В Python есть недокументированный оператор [обратная импликация](https://en.wikipedia.org/wiki/Converse_implication).
```py
>>> False ** False == True
True
>>> False ** True == False
True
>>> True ** False == True
True
>>> True ** True == True
True
```
**💡 Объяснение:** Если заменить `False` и `True` на 0 и 1 и произвести математические вычисления, то таблица истинности будет эквивалентна оператору обратной импликации. ([Источник](https://github.com/cosmologicon/pywat/blob/master/explanation.md#the-undocumented-converse-implication-operator))
* Раз уж мы заговорили об операторах, есть еще оператор `@` для умножения матриц (не волнуйтесь, на этот раз он настоящий).
```py
>>> import numpy as np
>>> np.array([2, 2, 2]) @ np.array([7, 8, 8])
46
```
**💡 Объяснение:** Оператор `@` был добавлен в Python 3.5 с учетом пожеланий научного сообщества. Любой объект может перегрузить магический метод `__matmul__`, чтобы определить поведение этого оператора.
* Начиная с Python 3.8 для быстрой отладки можно использовать типичный синтаксис f-строк, например `f'{some_var=}`. Пример,
```py
>>> some_string = "wtfpython"
>>> f'{some_string=}'
"some_string='wtfpython'"
```
* Python использует 2 байта для хранения локальных переменных в функциях. Теоретически это означает, что в функции может быть определено только 65536 переменных. Однако в python есть удобное решение, которое можно использовать для хранения более 2^16 имен переменных. Следующий код демонстрирует, что происходит в стеке, когда определено более 65536 локальных переменных (Внимание: этот код печатает около 2^18 строк текста, так что будьте готовы!):
```py
import dis
exec("""
def f():
""" + """
""".join(["X" + str(x) + "=" + str(x) for x in range(65539)]))
f()
print(dis.dis(f))
```
* Несколько потоков Python не смогут выполнять ваш *Python-код* одновременно (да, вы не ослышались!). Может показаться интуитивно понятным породить несколько потоков и позволить им выполнять ваш Python код одновременно, но из-за [Global Interpreter Lock](https://wiki.python.org/moin/GlobalInterpreterLock) в Python, все, что вы делаете, это заставляете ваши потоки выполняться на одном и том же ядре по очереди. Потоки Python хороши для задач, связанных с IO, но чтобы добиться реального распараллеливания в Python для задач, связанных с процессором, вы можете использовать модуль Python [multiprocessing](https://docs.python.org/3/library/multiprocessing.html).
* Иногда метод `print` может выводить значения с задержкой. Например,
```py
# Файл some_file.py
import time
print("wtfpython", end="_")
time.sleep(3)
```
Это выведет `wtfpython` через 3 секунды из-за аргумента `end`, потому что выходной буфер очищается либо при появлении `\n`, либо когда программа завершает выполнение. Мы можем принудительно отчистить буфер, передав аргумент `flush=True`.
* Срез списка индексом, превышающим длину списка, не приводит к ошибкам
```py
>>> some_list = [1, 2, 3, 4, 5]
>>> some_list[111:]
[]
```
* При срезе итерируемого объекта не всегда создается новый объект. Например,
```py
>>> some_str = "wtfpython"
>>> some_list = ['w', 't', 'f', 'p', 'y', 't', 'h', 'o', 'n']
>>> some_list is some_list[:] # Ожидается False, так как создан новый объект.
False
>>> some_str is some_str[:] # Возвращается True, потому что строки неизменны, создание нового объекта ничего не меняет
True
```
* `int('١٢٣٤٥٦٧٨٩')` возвращает `123456789` в Python 3. В Python десятичные символы включают в себя символы цифр и все символы, которые могут быть использованы для формирования десятично-радиксных чисел, например U+0660, ARABIC-INDIC DIGIT ZERO. Вот [интересная история](https://chris.improbable.org/2014/8/25/adventures-in-unicode-digits/), связанная с таким поведением Python.
* Начиная с Python 3 вы можете разделять числовые литералы символами подчеркивания (для лучшей читаемости).
```py
>>> six_million = 6_000_000
>>> six_million
6000000
>>> hex_address = 0xF00D_CAFE
>>> hex_address
4027435774
```
* `'abc'.count('') == 4`. Вот примерная реализация метода `count`, которая немного разъяснит ситуацию
```py
def count(s, sub):
result = 0
for i in range(len(s) + 1 - len(sub)):
result += (s[i:i + len(sub)] == sub)
return result
```
Такое поведение связано с совпадением пустой подстроки(`''`) со срезами длины 0 в исходной строке.
---
---