Можно ли создавать очень большие кортежи в Python?

У меня есть довольно большой список ( > 1K элементов) объектов одного типа в моей программе Python. Список никогда не изменяется - элементы не добавляются, не удаляются и не изменяются. Есть ли недостаток, чтобы помещать объекты в кортеж вместо списка?

С одной стороны, кортежи неизменяемы, чтобы соответствовать моим требованиям. С другой стороны, использование такого большого кортежа просто не так. На мой взгляд, кортежи всегда были для небольших коллекций. Это двойная, триплексная, четырехкратная... Не двухтысячная и пятидесятипятикратная.

Неужели мой страх перед большими кортежами оправдан? Неужели это плохо для производительности, беспризорной или плохой практики?

Ответ 1

В CPython, вперед. Под обложками единственное реальное различие между хранением списков и кортежей заключается в том, что массив C-уровня, содержащий элементы кортежа, выделяется в кортеже, а объект списка содержит указатель на массив C-уровня, содержащий элементы списка, который выделяется отдельно от объекта списка. Реализация списка должна сделать это, потому что список может расти, и поэтому памяти, содержащей вектор уровня C, может потребоваться изменить свой базовый адрес. Кортеж не может изменить размер, поэтому память для него выделяется непосредственно в объекте кортежа.

Я создал кортежи с миллионами элементов, и все же я жил, чтобы напечатать об этом; -)

Obscure

В CPython может даже быть "причиной" предпочтения гигантских кортежей: циклическая схема сбора мусора освобождает кортеж от периодического сканирования, если он содержит только неизменяемые объекты. Тогда кортеж никогда не может быть частью цикла, поэтому циклический gc может игнорировать его. Та же оптимизация не может использоваться для списков; просто потому, что список содержит только неизменяемые объекты в течение одного цикла циклического gc, который ничего не говорит о том, будет ли это происходить во время следующего прогона.

Это почти никогда не имеет особого значения, но он может сохранить процент или около того в долгосрочной перспективе, и преимущество освобождения гигантских кортежей растет тем больше, что они есть.

Ответ 2

Да, это нормально.

Однако, в зависимости от операций, которые вы выполняете, вы можете захотеть использовать функцию set в Python. Это преобразует ваш входной итерабельный (кортеж, список или другой) в набор. Наборы хороши по нескольким причинам, но особенно потому, что вы получаете уникальный список элементов, которые имеют постоянный поиск времени для элементов.

Нет ничего "не-pythonic" в отношении хранения больших наборов данных в памяти.