TGViewer
Python Заметки Python Заметки @pythonotes · 2.2K subscribers
Post #132 618
Допустим у нас есть какой-то список
Для сортировки этого списка у нас есть два пути:

🔸 функция sorted()

>>> a = [3, 1, 2]
>>> b = sorted(a)
>>> print(a, b)
[3, 1, 2] [1, 2, 3]

Думаю, всем очевидно что теперь a и b это разные объекты. Так работает sorted(), то есть получает один список, и возвращает другой список с изменениями. Исходный список не изменяется.

🔸 метод list.sort()

>>> a = [3, 1, 2]
>>> b = a.sort()
>>> print(a, b)
[1, 2, 3], None

Метод list.sort() не возвращает новый список. Он вообще ничего не возвращает. Он просто сортирует исходный список.

Надеюсь, уловили разницу? Но это было лишь вступление чтобы был ясна следующая тема.

На самом деле я хотел рассказать про операторы "=" и "+=" по отношению к спискам.
Все мы привыкли что запись

x += 3

Это просто более короткая версия записи

x = x + 3

Но это не всегда так.
Дело в том, что со списками оператор "+" работает аналогично функции sorted(), то есть возвращает новый объект, после чего оператор "=" записывает значение в переменную. В то время как "+=" работает аналогично методу list.sort() — изменяет исходный список.

Вот небольшой пример для проверки:

>>> a = [1, 2]
>>> b = a
>>> a = a + [3, 4]
>>> print(a, b)
[1, 2, 3, 4] [1, 2]

Во второй строке a и b ссылаются на один и тот же обеъект. Но после присвоения результата оператора сложения в переменную a мы создали новый объект и переписали ссылку a.

>>> a = [1, 2]
>>> b = a
>>> a += [3, 4]
>>> print(a, b)
[1, 2, 3, 4] [1, 2, 3, 4]

А в этом примере переменная a не перезаписалась, оператор отработал с исходным объектом. Поэтому мы изменили и b тоже.
Можете пройтись функцией id() чтобы точно всё проверить.

Данная фишка не сработает с кортежами, так как они неизменяемые. Оба варианта создают новый объект.

Пример, где это может вызвать неоднозначность. Класс, в атрибутах которого указывается список каких-то дефолтных полей. Во время создания инстанса мы можем их расширять через аргументы.

class MyClass:
L1 = [0]
L2 = [0]

def __init__(self, fields):
self.L1 = self.L1 + fields
self.L2 += fields

Класс имеет два статических атрибута.
В конструкторе класса в первом случае мы создаём новый атрибут инстанса L1 который своим именем перекрывает атрибут класса. Такое значение L1 будет только у этого инстанса.
Во втором случае мы меняем именно атрибут класса L2, то есть это будет видно во всех инстансах данного класса.

>>> obj1 = MyClass(fields=[1])
>>> print(obj1.L1, obj1.L2)
[0, 1] [0, 1]

>>> obj2 = MyClass(fields=[2])
>>> print(obj2.L1, obj2.L2)
[0, 2] [0, 1, 2]

>>> obj3 = MyClass(fields=[3])
>>> print(obj3.L1, obj3.L2)
[1, 3] [0, 1, 2, 3]

В атрибут класса L2 добавляется элемент при каждом создании инстанса.

#tricks
More from @pythonotes
  1. Sep 21, 2026­ WebAssembly это мощная технология позволяющая загружать практически любое приложение в б…
  2. Aug 17, 2026Не так давно столкнулся с API который в ответе с ошибкой присылал только статус-код. Без п…
  3. Jul 20, 2026У меня основная ОС это Linux. Но нередко требуется делать сборку клиента под Windows. Соби…
  4. Jul 13, 2026В прошлый раз был пример с понижением привелегий процесса. Проблема в том, что обратно под…
  5. Jul 6, 2026Модуль pwd может использоваться для считывания информации о пользователях из базы данных п…
  6. Jun 22, 2026Недавно я реализовал Multi Tenancy систему на FastAPI + SQLAlchemy и пересобрал её в небол…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →