Я работаю над проблемой, когда мне нужно манипулировать двоичными данными. Самый простой способ сделать это — использовать массивы, поскольку использование двоичного строкового представления не допускается. Я могу получить этот код или сделать то же самое, используя bin(), но числа всегда будут преобразованы в строку. Мне нужно использовать массив типа int или bool. Как это может быть сделано?
ascii = list("ABCD".encode('ascii'))
arr = list(map(lambda x: [*format(x, '08b')], ascii))
Я пытался использовать bin() и format() для получения двоичных строк в Python, но получил строковые результаты.
Мне нужно создать кодировку, которая достигается путем шифрования битов строки. Поэтому я сначала кодирую строку в ascii и пытаюсь получить двоичное представление этой строки.
Тааак? Как bin() не отвечает всем требованиям? Опять Как спросить и минимальный воспроизводимый пример!
Чего вы на самом деле пытаетесь достичь?






ascii = list("ABCD".encode('ascii'))
res = [[(byte >> (7 - i)) & 1 for i in range(8)] for byte in ascii]
print(res)
[[0, 1, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 0, 0, 1, 0, 0]]
numpy.array() и сохранить биты, если у вас было много операций:import numpy as np
ascii = list("ABCD".encode('ascii'))
res = []
for byte in ascii:
for i in range(8):
bit = (byte >> (7 - i)) & 1
res.append(bit)
print(np.array(res, dtype=bool))
[Ложь, правда, ложь, ложь, ложь, ложь, ложь, правда, ложь, правда, ложь. Ложь Ложь Ложь Верно Ложь Ложь Верно Ложь Ложь Ложь Ложь Правда, правда, ложь, правда, ложь, ложь, ложь, правда, ложь, ложь]
Разве Numpy не является излишним просто преобразовать 1 и 0 в True и ЛОЖЬ? Почему бы и нет: res.append(bool(bit)) или даже просто оставить их целыми числами? от @Марк
Каждый элемент в списке Python является объектом.
Массивы Numpy используют один тип элемента и не используют какой-либо тип динамически, как это делает список Python. Это делает массивы Numpy более эффективными для задач с интенсивными вычислениями.
Если бы мы имели дело с 10 миллионами операций, это было бы перебором. Но поскольку вопрос касается битовых манипуляций, размер данных может быть большим, а количество операций — большим, поэтому массивы Numpy являются эффективным выбором.
import time, sys, numpy
data = list(range(100000000))
L = list(data)
arr = numpy.array(data)
start = time.time()
list_mult = [x * 2 for x in L]
end = time.time()
print(f"List: {end - start} seconds")
start = time.time()
arr_mult = arr * 2
end = time.time()
print(f"Array: {end - start} seconds")
List: 12.309393882751465 seconds
Array: 2.8275811672210693 seconds
(byte >> (7 - i)) & 1:i = 0: (65 >> (7 - 0)) & 1 → (65 >> 7) & 1 → 00000000 & 1 → 0
i = 1: (65 >> (7 - 1)) & 1 → (65 >> 6) & 1 → 00000001 & 1 → 0
i = 2: (65 >> (7 - 2)) & 1 → (65 >> 5) & 1 → 00000010 & 1 → 1
i = 3: (65 >> (7 - 3)) & 1 → (65 >> 4) & 1 → 00000100 & 1 → 0
i = 4: (65 >> (7 - 4)) & 1 → (65 >> 3) & 1 → 00001000 & 1 → 0
i = 5: (65 >> (7 - 5)) & 1 → (65 >> 2) & 1 → 00010000 & 1 → 0
i = 6: (65 >> (7 - 6)) & 1 → (65 >> 1) & 1 → 00100000 & 1 → 0
i = 7: (65 >> (7 - 7)) & 1 → (65 >> 0) & 1 → 01000001 & 1 → 1
[False True False False False False False True # 'A' -> 01000001
False True True False False False False False # 'B' -> 01000010
False True True True False False False False # 'C' -> 01000011
False True True True False False True False] # 'D' -> 01000100
Обратите внимание, что побитовое & между любым битом и 1 возвращает сам бит, который эффективно отфильтровывает все остальные биты:
0 & 1 → 0
1 & 1 → 1
Разве Numpy не является излишним просто преобразовать 1 и 0 в True и False? Почему бы и нет: res.append(bool(bit)) или даже просто оставить их целыми?
У меня возникнет соблазн просто сделать: [[(byte >> (7 - i)) & 1 for i in range(8)] for byte in ascii] что даст вложенную структуру, которую, похоже, ищет ОП.
@Марк Обновлено. int тоже хорошо. Это призыв ОП. Не совсем понимаю масштаб проблемы.
Спасибо, принятый ответ работает хорошо. Логический массив не был необходим, поскольку список int удобен для моих нужд, поскольку я старался не использовать библиотеки. @user24714692 user24714692 Не могли бы вы объяснить, почему при генерации бита внутри внутреннего цикла нам нужно «& 1». Я не понимаю, почему нельзя было использовать необработанный бит, выбранный сдвигом, но это кажется необходимым.
Итак, вы используете преобразование чисел в двоичные строки и недовольны получением двоичных строк? Чего именно вы хотите? Какой «манипуляции» вам нужно добиться? Как спросить и минимальный воспроизводимый пример.