Есть ли способ получить массив двоичных чисел без предварительного преобразования его в строку?

Я работаю над проблемой, когда мне нужно манипулировать двоичными данными. Самый простой способ сделать это — использовать массивы, поскольку использование двоичного строкового представления не допускается. Я могу получить этот код или сделать то же самое, используя bin(), но числа всегда будут преобразованы в строку. Мне нужно использовать массив типа int или bool. Как это может быть сделано?

ascii = list("ABCD".encode('ascii'))
arr = list(map(lambda x: [*format(x, '08b')], ascii))

Я пытался использовать bin() и format() для получения двоичных строк в Python, но получил строковые результаты.

Итак, вы используете преобразование чисел в двоичные строки и недовольны получением двоичных строк? Чего именно вы хотите? Какой «манипуляции» вам нужно добиться? Как спросить и минимальный воспроизводимый пример.

Julien 30.05.2024 03:51

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

SwigitySwogity 30.05.2024 04:02

Тааак? Как bin() не отвечает всем требованиям? Опять Как спросить и минимальный воспроизводимый пример!

Julien 30.05.2024 04:26

Чего вы на самом деле пытаетесь достичь?

juanpa.arrivillaga 30.05.2024 05:01
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Понимание списка: (@Mark в комментарии)

  • Поскольку у вас, похоже, не так много операций, для сохранения битов подойдет список списков:
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)) или даже просто оставить их целыми?

Mark 30.05.2024 04:36

У меня возникнет соблазн просто сделать: [[(byte >> (7 - i)) & 1 for i in range(8)] for byte in ascii] что даст вложенную структуру, которую, похоже, ищет ОП.

Mark 30.05.2024 04:42

@Марк Обновлено. int тоже хорошо. Это призыв ОП. Не совсем понимаю масштаб проблемы.

user24714692 30.05.2024 04:55

Спасибо, принятый ответ работает хорошо. Логический массив не был необходим, поскольку список int удобен для моих нужд, поскольку я старался не использовать библиотеки. @user24714692 user24714692 Не могли бы вы объяснить, почему при генерации бита внутри внутреннего цикла нам нужно «& 1». Я не понимаю, почему нельзя было использовать необработанный бит, выбранный сдвигом, но это кажется необходимым.

SwigitySwogity 30.05.2024 07:00

Другие вопросы по теме

Похожие вопросы

Как расшифровать ключ, зашифрованный с помощью пакета натрия R в Python?
К чему относится ошибка «модуль langchain» не имеет атрибута «verbose»?
Почему VS Code показывает встроенные комментарии как часть переменных среды из файла .env?
Как избежать или обойти еженедельный повторный ввод учетных данных для Interactive Broker Gateway (IBGW), чтобы поддерживать соединение?
Оптимизация размещения узлов в 2D-сетке для соответствия определенным геодезическим расстояниям
Проблемы с потоками и горячими клавишами при использовании Pynput в Python (бесконечный цикл и скорость реагирования)
Полярный контурный график с нерегулярными «ячейками»
Почему распаковка списка при индексации является синтаксической ошибкой в ​​Python 3.8, но не в Python 3.12?
Python TypeError: невозможно объединить объект типа '<class 'str'>'; действительны только объекты Series и DataFrame
Установка правильной версии драйвера Chrome для Chrome в Docker