2016-04-19 6 views
1

Есть ли структура данных в Python 3, которая представляет собой массив логических True или False? Кроме того, будет ли этот массив более эффективным с памятью, чем массив байтов?Есть ли изменяемый двоичный массив в python?

Мне нужно изменить значение от True до False и получить доступ к нему по индексу; но мне не нужно изменять размер массива.

редактировать: кроме того, если команда перемещения будет быстрее, чем индексации, это было бы неплохо также

+0

Возможный дубликат [Как создать массив бит в Python?] (Http://stackoverflow.com/questions/11669178/how-to-create-an-array-of-bits-in-python) – ShadowRanger

ответ

0

Как насчет использования массива?

import array 
a = array.array("B", [0]*10) #fix size of 10 - all False 

a[1] = 1 # Mutable, Yay! 
print(a) 

Он будет использовать наименьшее количество памяти, и даст вам O (1) индексация

+0

Будет ли этот массив более эффективным с памятью, чем массив байтов? – user4757074

+0

FYI, ['bytearray', доступный с версии 2.6] (https://docs.python.org/2/library/functions.html#bytearray) не требует импорта или использования кодов формата и намного эффективнее для определенные цели (в 2.x, 'array' не поддерживает буферный протокол, он не может использоваться w /' memoryview' или другие API, которым нужны «байтовые объекты», 'bytearray' поддерживает буферный протокол) , Кроме того, инициализация 'array' с помощью' [0] * x означает временный «список» 4-8x, ​​размер результата, а затем его итерацию; 'array.array ('B', b '\ 0' * 10)' (или 'b '\ 1' * 10) в 2 раза быстрее и становится еще быстрее по мере увеличения размера. – ShadowRanger

+0

@ user4757074: 'array.array ('B')' _is_ a (динамический) массив байтов (в смысле C), так же, как 'bytearray'. Каждое дополнительное значение будет стоить (амортизируется, оно растет с помощью мультипликативного процесса для минимизации повторных обменов), один дополнительный байт для хранения, вместо «списка» или «кортежа», который будет стоить одной переменной размера указателя для каждого значения (так что 4 или 8 байтов на 32 и 64-битных архитектурах соответственно), пока 'list' /' tuple' заполняется только 0/'False и 1 /' True' (которые являются одноточечными в CPython, поэтому вы не оплачиваете накладные расходы для каждая отдельная ссылка на них). – ShadowRanger

0

Как правило, это лучше оплатить счет использования байта на значение, а не немного, и вы можно использовать bytearray (встроенный, так как 2.6) для этой цели:

a = bytearray(100)   # 100 values all initialized to 0/False 
# or initially true: 
b = bytearray(b'\x01' * 100) # 100 values all initialized to 1/True 

# While you'll get 0 and 1 back, True and False can be assigned to it 
a[1] = True 
b[1] = False 

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

Если вам действительно нужно место для большого количества флагов, вам нужен сторонний пакет, который оптимизирует получение одного бита за значение, например. bitarray (расширение C для максимальной скорости, но все еще медленнее, чем bytearray для многих целей) или bitvector или bitstring (Pure Python, чтобы свести к минимуму сложности компиляции, а иногда и предоставлять дополнительные функции более легко, но надежно медленнее, чем bytearray, если не ограничено памятью).