Эффективность Python: списки против кортежей - PullRequest
8 голосов
/ 19 мая 2011

У меня среднее количество базовых объектов.

Эти базовые объекты будут помещены в коллекции, и эти коллекции будут группироваться: отсортированные, усеченные и т. Д.

К сожалению, n достаточно велик, так что потребление памяти немного беспокоит, и скорость становится все более опасной.

Мое понимание заключается в том, что кортежи немного более эффективны с точки зрения памяти, поскольку они дедуплицированы.

В любом случае, я хотел бы знать, каковы соотношения между процессорами и памятью списков и кортежей в Python 2.6 / 2.7.

Ответы [ 7 ]

16 голосов
/ 19 мая 2011

Если у вас есть кортеж и список с одинаковыми элементами, кортеж занимает меньше места. Поскольку кортежи являются неизменяемыми, вы не можете их сортировать, добавлять к ним и т. Д. Я рекомендую посмотреть этот доклад Алекса Гейнора , чтобы быстро ознакомиться с выбором структуры данных в Python.

ОБНОВЛЕНИЕ: Подумав об этом еще, вы можете подумать об оптимизации использования пространства вашими объектами, например, через __slots__ или используя namedtuple экземпляров в качестве прокси вместо реальных объектов. Это, вероятно, приведет к гораздо большей экономии, так как у вас их N и (предположительно) только несколько коллекций, в которых они появляются. namedtuple в частности супер супер; проверить Рэймонд Хеттингер говорит .

9 голосов
/ 19 мая 2011

Как и другие упомянутые кортежи неизменны.Сортировка кортежа (например, sorted(mytuple)) возвращает список, который вы затем должны были бы преобразовать обратно в кортеж.

Чтобы отсортировать кортеж (и сохранить его как кортеж), вам нужно сделать это:

mytuple = (3,2,1)
mysortedtuple = tuple(sorted(mytuple))

Чтобы отсортировать список, вам нужно сделать следующее:

mylist = [3,2,1]
mylist.sort()

Поскольку вы не используете приведение и повторное приведение, последний, в данном случае, болееЭффективно.

Не зацикливайтесь на использовании кортежей над списками, если у вас нет веских оснований.Если вам нужны отсортированные данные, кортежи не подходят, если они не созданы таким образом.Кортежи работают лучше, когда содержащиеся в них данные НЕ ИЗМЕНЯЮТСЯ, например, с параметрами конфигурации, загруженными во время выполнения, или с данными, которые уже были обработаны.

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

Дополнительная литература:

4 голосов
/ 28 мая 2011

Каково (среднее, минимальное, максимальное) количество базовых объектов в коллекции?

Кортежи являются "дедуплицированными", а списки - нет?Как вы думаете, что означает «дедупликация» в этом контексте?

Списки занимают больше памяти, чем кортежи, потому что дополнительная память выделяется при условии, что список будет расти, а вы определенно не хотитев realloc () памяти каждый раз, когда вы делаете large_list.append ().Однако на 32-разрядной машине амортизированная стоимость дополнительного элемента списка составляет 4 байта для указателя, N байтов для самого элемента и не более 4 байтов для дополнительной памяти.N равно 16 байтам для числа с плавающей запятой.Это означает, что список с плавающей запятой занимает до 24 байтов на дополнительный, по сравнению с 20 байтами для кортежа.«Базовый объект» с N == 100 дает сравнение 108 против 104. Если базовый объект упоминается в двух коллекциях, то 58 против 54. Насколько велик ваш N?

Совет: оставьте свойколлекции в виде списков.Сконцентрируйтесь на:

  • , гарантирующем, что ваши базовые объекты эффективны для памяти

  • используйте генераторы и полезности itertools вместо временных списков, где это возможно

  • если вы не можете избежать временных списков, убедитесь, что они немедленно выбрасываются, они больше не нужны, т. Е. Не ждите возврата метода создания;используйте явный del как можно скорее.

3 голосов
/ 28 мая 2011

В дополнение ко всем этим предложениям вы можете обнаружить, что numpy удовлетворит ваши потребности.Если ваши объекты являются чем-то, что numpy обрабатывает по умолчанию (целочисленные значения, нативные типы C и т. Д.), То это было бы идеально.Вы также можете использовать пустой массив с пользовательскими объектами, но это может потребовать больше усилий, чем оно того стоит.

2 голосов
/ 19 мая 2011

Вы не можете использовать их одинаково. Кортежи являются неизменяемыми и не поддерживают добавление, сортировку и т. Д. (Вызов sorted для кортежа дает список и т. Д.). Кортежи полностью отличаются от списков, поэтому любое сравнение производительности не имеет смысла.

1 голос
/ 19 мая 2011

Существует как минимум два существующих вопроса, которые достаточно похожи на ваши, поэтому ответы (или ссылки внутри них) могут быть вам полезны. Подводя итог: позвольте особенностям типа (изменяемые и неизменные, неоднородные или однородные), а не производительности, направлять ваше решение, потому что различия производительности / эффективности минимальны.

В чем разница между списком и кортежами в Python?
Каковы различия между списком, словарем и кортежем в Python?

1 голос
/ 19 мая 2011

Невозможно отсортировать неизменный объект, т. Е. При сортировке кортежа вы всегда создадите новый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...