Python int в двоичную строку?

530

Существуют ли какие-либо постоянные методы Python для преобразования Integer (или Long) в двоичную строку в Python?

В Google существует множество функций dec2bin () ... Но я надеялся, что смогу использовать встроенную функцию / библиотеку.

Nate
источник
С другой стороны, для чистого алгоритма обработки строк, смотрите это .
CopyPasteIt

Ответы:

750

Метод строкового формата Python может принимать спецификацию формата.

>>> "{0:b}".format(37)
'100101'

Формат спецификации документов для Python 2

Формат спецификации документов для Python 3

Тунг Нгуен
источник
86
str.format()просто отформатировать одно значение излишне. Идите прямо к format()функции : format(n, 'b'). Нет необходимости анализировать заполнитель и сопоставлять его с аргументом, переходя непосредственно к самой операции форматирования значения. Используйте, только str.format()если вам нужно поместить отформатированный результат в более длинную строку (например, использовать его как шаблон).
Мартин Питерс
29
@mike: Или используйте спецификацию форматирования. Добавьте количество цифр с лидирующей 0строкой форматирования: отформатируйте format(10, '016b')до 16 цифр с начальными нулями.
Мартин Питерс
Не в этом случае 0в "{0:b}"может быть отброшен нет? Я имею в виду, в случае, когда форматируется только одно число, это правильно "{:b}", не так ли?
Томасяны
1
обычно используется 4/8 / ... битное представление:"{:08b}".format(37)
Sparkler
2
f "{37: b}" в Python3.7 или новее.
DA
471

Если вы ищете bin()в качестве эквивалента hex(), он был добавлен в Python 2.6.

Пример:

>>> bin(10)
'0b1010'
Джон Фухи
источник
66
Также обратите внимание, что это быстрее сделать str(bin(i))[2:](0,369 с для 1000000опсов), чем "{0:b}".format(i)(0,721 с для 1000000опс)
mVChr
64
@mVChr Если кто-то конвертирует числа в двоичное представление ASCII, я действительно надеюсь, что скорость не имеет значения.
Ник Т
29
@mVChr: str.format()в любом случае это неправильный инструмент, вы бы использовали format(i, 'b')вместо этого. Примите во внимание, что это также дает вам варианты отступов и выравнивания; format(i, '016b')отформатировать в 16-битное двоичное число с нулевым дополнением. Чтобы сделать то же самое с bin()вами, вам нужно добавить str.zfill()вызов: bin(i)[2:].zfill(16)(не нужно звонить str()!). format()Читаемость и гибкость (с динамическим форматированием гораздо сложнее bin()) являются отличным компромиссом: не оптимизируйте для производительности, если не нужно, до тех пор оптимизируйте для удобства сопровождения.
Мартин Питерс
Что означает [2:]?
zero_cool
4
Конечно, с Python 3.6+ теперь можно использовать f"{37:b}".
Люк Дэвис
63

Python на самом деле уже имеет что-то встроенное для этого, возможность выполнять такие операции, как '{0:b}'.format(42), что даст вам битовый шаблон (в строке) для 42, или 101010.


Для более общей философии ни один язык или библиотека не предоставит своим пользователям все, что они пожелают. Если вы работаете в среде, которая не обеспечивает именно то, что вам нужно, вы должны собирать фрагменты кода по мере разработки, чтобы вам никогда не приходилось писать одно и то же дважды. Например, псевдокод:

define intToBinString, receiving intVal:
    if intVal is equal to zero:
        return "0"
    set strVal to ""
    while intVal is greater than zero:
        if intVal is odd:
            prefix "1" to strVal
        else:
            prefix "0" to strVal
        divide intVal by two, rounding down
    return strVal

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

Общая идея заключается в использовании кода из (в порядке предпочтения):

  • язык или встроенные библиотеки.
  • сторонние библиотеки с подходящими лицензиями.
  • Ваша собственная коллекция.
  • что-то новое, что вам нужно написать (и сохранить в своей коллекции на потом).
paxdiablo
источник
1
Несколько хороших советов в этом ответе. Жаль только, что код слишком медленный. Вы предлагаете O (N ^ 2) алгоритм, где O (N) будет делать. Проблемная часть в s = "1" + sи s = "0" + sстроки. Каждый делает ненужную копию с. Вы должны повернуть строку прямо перед тем, как ее вернуть.
Андреас Магнуссон
@ Андреас, я предложил использовать '{0:b}'.format(42)медленный метод - просто пример того, как сделать это в общем, что может быть или не быть O (n ^ 2) в зависимости от используемого языка. Это выглядит только как Python, так как Python - идеальный язык псевдокода, поэтому я изменю это, чтобы прояснить.
paxdiablo
На самом деле это был бы довольно эзотерический язык, где s = "1" + sне было O (N), когда sэто строковый тип. Может быть, язык, где все строки хранятся в обратном порядке, или каждый символ является узлом в связанном списке? Для любого типичного языка строка - это массив символов. В этом случае префикс строки требует, чтобы была сделана копия, как еще вы собираетесь поместить символ перед другими символами?
Андреас Магнуссон
Я легко могу представить строковый тип, который состоит из блока памяти, в котором строка выровнена по правому краю внутри этого блока, и смещения его начального символа. Чтобы добавить префикс к символу, вы просто уменьшите смещение и сохраните его там. Да, это было бы эзотерически, но для меня не имеет смысла спорить о возможных реальных проблемах с небольшим количеством псевдокода, тем более, что у вас вряд ли будет более нескольких десятков битов / итераций. Даже очень плохая сортировка пузырьков является адекватной, если ваш размер данных мал :-) В любом случае, я добавлю примечание об эффективности.
paxdiablo
Конечно, если эффективность важна, вы, вероятно, не выбрали бы python для начала. Тем не менее, по моему опыту, довольно часто случается, что код, который был написан наивно с использованием алгоритма O (N²) и протестирован с небольшим набором данных, быстро используется с гораздо большим набором данных, потому что «кажется, он работает». И вдруг у вас появляется код, который запускается часами, а исправление может занять всего несколько секунд. Алгоритмы O (N²) коварны, потому что, кажется, они работают какое-то время, но когда ваши данные масштабируются, они этого не делают, и к тому времени тот, кто их написал, ушел, и никто не знает, почему все происходит вечно.
Андреас Магнуссон
41

Если вы хотите текстовое представление без префикса 0b, вы можете использовать это:

get_bin = lambda x: format(x, 'b')

print(get_bin(3))
>>> '11'

print(get_bin(-3))
>>> '-11'

Когда вы хотите n-битное представление:

get_bin = lambda x, n: format(x, 'b').zfill(n)
>>> get_bin(12, 32)
'00000000000000000000000000001100'
>>> get_bin(-12, 32)
'-00000000000000000000000000001100'

В качестве альтернативы, если вы предпочитаете иметь функцию:

def get_bin(x, n=0):
    """
    Get the binary representation of x.

    Parameters
    ----------
    x : int
    n : int
        Minimum number of digits. If x needs less digits in binary, the rest
        is filled with zeros.

    Returns
    -------
    str
    """
    return format(x, 'b').zfill(n)
Мартин Тома
источник
5
Или просто использовать format(integer, 'b'). bin()является средством отладки, специально предназначенным для создания двоичного целочисленного литерального синтаксиса Python , format()предназначенного для создания определенных форматов.
Мартин Питерс
1
@MartijnPieters Большое спасибо за упоминание этого. Я скорректировал свое решение. Откуда вы знаете, что bin()это инструмент отладки, предназначенный для создания двоичного целочисленного литерального синтаксиса Python? Я не мог найти это в документации.
Мартин Тома
2
Из документации: Результатом является правильное выражение Python . Его целью является создание выражения Python, а не представление конечного пользователя. То же самое относится oct()и к hex().
Мартин Питерс
4
Другие альтернативы: Если вы собираетесь сделать ширину динамической, вместо нее str.zfill()вы можете использовать str.format()или format()с динамическим вторым аргументом: '{0:0{1}b}'.format(x, n)или format(b, '0{}b'.format(n)).
Мартин Питерс
@MartijnPieters Wow, большое спасибо за этот вклад! Я не знал, что это было возможно с форматом. Тем не менее, я думаю, что мой текущий ответ zfillлегче читать и понимать, чем второй динамический аргумент, так что я его оставлю.
Мартин Тома
38

Как ссылка:

def toBinary(n):
    return ''.join(str(1 & int(n) >> i) for i in range(64)[::-1])

Эта функция может преобразовывать положительное целое число размером 18446744073709551615до строки, представленной в виде строки '1111111111111111111111111111111111111111111111111111111111111111'.

Его можно изменить, чтобы он служил гораздо большему целому числу, хотя это может быть не так удобно, как "{0:b}".format()или bin().

kctong529
источник
@GarethDavidson какая версия это? Явное указание этого может быть более полезным в будущем при поиске в Google.
Вольф
Это была версия 2.7, я думаю. Я сомневаюсь, что это сработает в 3.x
Гарет Дэвидсон
17

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

>> "{0:b}".format(10)
'1010'

И если вы хотите иметь фиксированную длину двоичной строки, вы можете использовать это:

>> "{0:{fill}8b}".format(10, fill='0')
'00001010'

Если требуется дополнение до двух, то можно использовать следующую строку:

'{0:{fill}{width}b}'.format((x + 2**n) % 2**n, fill='0', width=n)

где n - ширина двоичной строки.

Xiang
источник
16

Это для Python 3 и держит ведущие нули!

print(format(0, '08b'))

введите описание изображения здесь

grepit
источник
1
Я ценю простой ответ.
reergymerej
14

однострочник с лямбдой :

>>> binary = lambda n: '' if n==0 else binary(n/2) + str(n%2)

тестовое задание:

>>> binary(5)
'101'



РЕДАКТИРОВАТЬ :

но потом :(

t1 = time()
for i in range(1000000):
     binary(i)
t2 = time()
print(t2 - t1)
# 6.57236599922

по сравнению с

t1 = time()
for i in range(1000000):
    '{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232
Азиз Альто
источник
который возвращает '' для 0, хотя. Разве нормальное представление для 0 не будет '0'?
диетическое питание
если вы хотите увидеть 0 :), вы можете заменить ''на '0', но это добавит начальный 0 для любого числа.
Азиз Альто
11

Резюме альтернатив:

n=42
assert  "-101010" == format(-n, 'b')
assert  "-101010" == "{0:b}".format(-n)
assert  "-101010" == (lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:])(-n)
assert "0b101010" == bin(n)
assert   "101010" == bin(n)[2:]   # But this won't work for negative numbers.

Авторы включают Джон Фухи , Тунг Нгуен , mVChr , Мартин Тома . и Мартейн Питерс.

BobStein-VisiBone
источник
6
str.format()просто отформатировать одно значение излишне. Идите прямо к format()функции: format(n, 'b'). Нет необходимости разбирать заполнитель и сопоставлять его с аргументом таким образом.
Мартин Питерс
10

Поскольку в предыдущих ответах в основном использовался format (), здесь представлена ​​реализация f-строки.

integer = 7
bit_count = 5
print(f'{integer:0{bit_count}b}')

Вывод:

00111

Для удобства вот ссылка на документы Python для форматированных строковых литералов: https://docs.python.org/3/reference/lexical_analysis.html#f-strings .

Джон Форбс
источник
5

Используя numpy pack / unpackbits, они ваши лучшие друзья.

Examples
--------
>>> a = np.array([[2], [7], [23]], dtype=np.uint8)
>>> a
array([[ 2],
       [ 7],
       [23]], dtype=uint8)
>>> b = np.unpackbits(a, axis=1)
>>> b
array([[0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
западня
источник
Вопрос о строковом представлении. Тем не менее, это было именно то, что я искал, не пройдя сначала строку! :)
Том Хейл
DOCO говорит: распаковывает элементы uint8массива в выходной массив двоичного-значной. Так хорошо для значений до 255.
Том Хейл
5

Для тех из нас, кому необходимо преобразовать целые числа со знаком (диапазон -2 ** (цифры-1) в 2 ** (цифры-1) -1) в двоичные строки, дополняющие 2, это работает:

def int2bin(integer, digits):
if integer >= 0:
    return bin(integer)[2:].zfill(digits)
else:
    return bin(2**digits + integer)[2:]

Это производит:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'
DeanM
источник
4

Еще одно решение с другим алгоритмом с использованием побитовых операторов.

def int2bin(val):
    res=''
    while val>0:
        res += str(val&1)
        val=val>>1     # val=val/2 
    return res[::-1]   # reverse the string

Более быстрая версия без изменения строки.

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 
Реза Абтин
источник
Вторая версия определенно не быстрее, так как в итоге вы получите что-то вроде алгоритма O (N ^ 2) вместо O (N). Я видел, как такие вещи убивают приложение (с точки зрения производительности), потому что разработчик думал, что выполнение дополнительного прохода в конце медленнее, чем выполнение каких-то дополнительных действий в первом цикле. После исправления время работы сократилось с дней до секунд.
Андреас Магнуссон
4
def binary(decimal) :
    otherBase = ""
    while decimal != 0 :
        otherBase  =  str(decimal % 2) + otherBase
        decimal    //=  2
    return otherBase

print binary(10)

вывод:

1010

Mukundan
источник
4

Вы можете сделать так:

bin(10)[2:]

или :

f = str(bin(10))
c = []
c.append("".join(map(int, f[2:])))
print c
Скиллер Дз
источник
bin (n) .replace ("0b", "")
маленький сан
3

Вот код, который я только что реализовал. Это не метод, но вы можете использовать его как готовую функцию !

def inttobinary(number):
  if number == 0:
    return str(0)
  result =""
  while (number != 0):
      remainder = number%2
      number = number/2
      result += str(remainder)
  return result[::-1] # to invert the string
quents
источник
3

Вот простое решение с использованием функции divmod (), которая возвращает напоминание и результат деления без дроби.

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin
user210021
источник
Требуется отладка. Вызов dectobin(10)привел к '0101'
Нейт
3

numpy.binary_repr(num, width=None)

Примеры из документации по ссылке выше:

>>> np.binary_repr(3)
'11'
>>> np.binary_repr(-3)
'-11'
>>> np.binary_repr(3, width=4)
'0011'

Дополнение к двум возвращается, когда входное число отрицательно и указана ширина:

>>> np.binary_repr(-3, width=3)
'101'
>>> np.binary_repr(-3, width=5)
'11101'
Том Хейл
источник
2

Несколько похожее решение

def to_bin(dec):
    flag = True
    bin_str = ''
    while flag:
        remainder = dec % 2
        quotient = dec / 2
        if quotient == 0:
            flag = False
        bin_str += str(remainder)
        dec = quotient
    bin_str = bin_str[::-1] # reverse the string
    return bin_str 
лавочник
источник
2

Вот еще один способ использования обычной математики, без циклов, только рекурсия. (Тривиальный случай 0 ничего не возвращает).

def toBin(num):
  if num == 0:
    return ""
  return toBin(num//2) + str(num%2)

print ([(toBin(i)) for i in range(10)])

['', '1', '10', '11', '100', '101', '110', '111', '1000', '1001']
ergonaut
источник
2

Калькулятор со всеми необходимыми функциями для DEC, BIN, HEX: (сделано и протестировано с Python 3.5)

Вы можете изменить входные тестовые числа и получить преобразованные.

# CONVERTER: DEC / BIN / HEX

def dec2bin(d):
    # dec -> bin
    b = bin(d)
    return b

def dec2hex(d):
    # dec -> hex
    h = hex(d)
    return h

def bin2dec(b):
    # bin -> dec
    bin_numb="{0:b}".format(b)
    d = eval(bin_numb)
    return d,bin_numb

def bin2hex(b):
    # bin -> hex
    h = hex(b)
    return h

def hex2dec(h):
    # hex -> dec
    d = int(h)
    return d

def hex2bin(h):
    # hex -> bin
    b = bin(h)
    return b


## TESTING NUMBERS
numb_dec = 99
numb_bin = 0b0111 
numb_hex = 0xFF


## CALCULATIONS
res_dec2bin = dec2bin(numb_dec)
res_dec2hex = dec2hex(numb_dec)

res_bin2dec,bin_numb = bin2dec(numb_bin)
res_bin2hex = bin2hex(numb_bin)

res_hex2dec = hex2dec(numb_hex)
res_hex2bin = hex2bin(numb_hex)



## PRINTING
print('------- DECIMAL to BIN / HEX -------\n')
print('decimal:',numb_dec,'\nbin:    ',res_dec2bin,'\nhex:    ',res_dec2hex,'\n')

print('------- BINARY to DEC / HEX -------\n')
print('binary: ',bin_numb,'\ndec:    ',numb_bin,'\nhex:    ',res_bin2hex,'\n')

print('----- HEXADECIMAL to BIN / HEX -----\n')
print('hexadec:',hex(numb_hex),'\nbin:    ',res_hex2bin,'\ndec:    ',res_hex2dec,'\n')
HKC72
источник
2

Для вычисления двоичных чисел:

print("Binary is {0:>08b}".format(16))

Для вычисления десятичного числа гекса :

print("Hexa Decimal is {0:>0x}".format(15))

Рассчитать все двоичные нет до 16:

for i in range(17):
   print("{0:>2}: binary is {0:>08b}".format(i))

Для вычисления гекса десятичного числа нет до 17

 for i in range(17):
    print("{0:>2}: Hexa Decimal is {0:>0x}".format(i))
##as 2 digit is enogh for hexa decimal representation of a number
Раджеш Кумар Саху
источник
1

Если вы готовы отказаться от «чистого» Python, но получить много огневой мощи, есть Sage - пример здесь :

sage: a = 15
sage: a.binary()
'1111'

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

sage: eval('0b'+b)
15
kcrisman
источник
1
try:
    while True:
        p = ""
        a = input()
        while a != 0:
            l = a % 2
            b = a - l
            a = b / 2
            p = str(l) + p
        print(p)
except:
    print ("write 1 number")
user7930187
источник
6
Возможно, стоит добавить какое-то объяснение тому, что вы там сделали.
Artless
1

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

import numpy as np
E_mat = np.tile(E,[1,M])
M_order = pow(2,(M-1-np.array(range(M)))).T
bindata = np.remainder(np.floor(E_mat /M_order).astype(np.int),2)

Eвходные десятичные данные, Mэто двоичные порядки. bindataвыводятся двоичные данные в формате 1 на M двоичной матрицы.

Галле Хе
источник
0

Вот простой двоичный в десятичный преобразователь, который непрерывно зацикливается

t = 1
while t > 0:
    binaryNumber = input("Enter a binary No.")
    convertedNumber = int(binaryNumber, 2)

    print(convertedNumber)

print("")
Спенсер Лэйленд
источник
Это обратный порядок того, что хочет ОП. Они ищут int в двоичный файл. Вы предоставляете двоичный файл для int.
Сесилия
0

Это мой ответ, он работает хорошо ..!

def binary(value) :
    binary_value = ''
    while value !=1  :
        binary_value += str(value%2)
        value = value//2
    return '1'+binary_value[::-1]
Чаруни Хансика А.М.
источник
Что если вы передадите значение 0? Например binary(0), вы получите то, что ожидаете?
Андреас Магнуссон