Python int до двійкового рядка?


529

Чи існують консервовані методи Python для перетворення цілого (або довгого) у бінарний рядок в Python?

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


Для зворотного взяття, для чистого алгоритму обробки рядків, дивіться це .
— CopyPasteIt

Відповіді:


750

Метод формату рядка Python може приймати специфікацію формату.

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

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

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


86
str.format()просто відформатувати одне значення є надмірним. Ідіть прямо до format()функції : format(n, 'b'). Немає необхідності розбирати заповнювач та приєднувати його до аргументу, перейдіть безпосередньо до самої операції форматування значення. Використовуйте лише в тому str.format()випадку, якщо вам потрібно розмістити відформатований результат у більш довгій строці (наприклад, використовувати його як шаблон).
— Martijn Pieters

29
@mike: Або використовувати специфікацію форматування. Додайте кількість розрядів, що ведуть 0до рядка форматування: format(10, '016b')формати до 16 цифр з провідними нулями.
— Martijn Pieters

У цьому випадку 0ін "{0:b}"може бути відпущено ні? Я маю на увазі, що у випадку, коли форматується лише одне число, це правильно "{:b}", чи не так?
— tomasyany

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()) великі компроміси, не оптимізуйте продуктивність, якщо вам не доведеться, до цього часу оптимізуйте для ремонту.
— Martijn Pieters

Що означає [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

який побудує ваш двійковий рядок на основі десяткового значення. Просто майте на увазі , що це родове трохи псевдо-коду , який не може бути найбільш ефективний спосіб зробити це , хоча, з ітерацій ви , здається, пропонує, це не матиме великого значення. Це насправді просто призначене як настанова про те, як це можна зробити.

Загальна ідея полягає у використанні коду з (у порядку уподобання):

  • мова або вбудовані бібліотеки.
  • сторонні бібліотеки з відповідними ліцензіями.
  • власну колекцію.
  • щось нове, що вам потрібно написати (і зберегти у власній колекції на потім).

1
Деякі хороші поради в цій відповіді. Лише дуже погано, що код непотрібно повільний. Ви пропонуєте O (N ^ 2) альго, де O (N) зробив би. Проблемна частина знаходиться в рядках s = "1" + sі s = "0" + s. Кожен робить непотрібну копію s. Ви повинні повернути рядок безпосередньо перед поверненням.
— Андреас Магнуссон

@Andreas, те, що я запропонував, було використовувати '{0:b}'.format(42), повільний метод був просто прикладом того, як це зробити загально, що може бути, а може і не бути O (n ^ 2) залежно від фактичної мови, що використовується. Це схоже лише на Python, оскільки Python є ідеальною мовою псевдокоду, тому я зміню це, щоб зробити його зрозумілим.
— paxdiablo

Насправді це була б досить езотерична мова, де s = "1" + sне було O (N), коли sце рядковий тип. Можливо, мова, де всі рядки зберігаються назад або кожен символ є вузлом у пов'язаному списку? Для будь-якої типової мови рядок - це в основному масив символів. У цьому випадку для префіксації рядка потрібно зробити копію, як ще ви збираєтесь поставити символ перед іншими символами?
— Андреас Магнуссон

Я можу легко передбачити тип рядка, який складається з блоку пам'яті, де рядок є правильно виправданим у цьому блоці, і зміщення його початкового символу. Щоб встановити префікс, ви просто зменшите зсув і збережіть його там. Так, це було б езотеричним, але мені мало сенсу сперечатися про можливі проблеми з реальним світом з невеликим псевдокодом, тим більше, що ви, швидше за все, не матимете кілька десятків біт / ітерацій. Навіть сильно злісний сорт бульбашок є адекватним, якщо розмір ваших даних невеликий :-) У будь-якому випадку я додам примітку про ефективність.
— paxdiablo

Звичайно, якщо важлива ефективність, ви, мабуть, не обираєте пітон для початку. Але, на моєму досвіді, досить часто трапляється, що код, написаний наївно за допомогою альго 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()призначений для отримання конкретних форматів.
— Martijn Pieters

1
@MartijnPieters Дякую вам дуже за те, що ви згадали про це. Я налагодив розчинення. Звідки ви знаєте, що bin()це інструмент налагодження, спрямований на створення синтаксису бінарного цілого чисел Python з буквами? Я не міг цього знайти в документації.
— Мартін Тома

2
З документації: Результат - допустимий вираз Python . Його мета - створити вираз Python, а не створювати уявлення кінцевих користувачів. Те саме стосується oct()і hex().
— Martijn Pieters

4
Більше альтернатив: Якщо ви збираєтеся зробити ширину динамічною, замість цього str.zfill()ви можете використовувати str.format()або format()з другим динамічним аргументом: '{0:0{1}b}'.format(x, n)або format(b, '0{}b'.format(n)).
— Martijn Pieters

@MartijnPieters Вау, дуже дякую за цей вклад! Я не знав, що це можливо з форматом. Однак я думаю, що мою сьогоднішню відповідь zfillлегше прочитати та зрозуміти, ніж динамічний другий аргумент, тому я буду її тримати.
— Мартін Тома

37

В якості довідки:

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

Ця функція може конвертувати додатне ціле число великим 18446744073709551615, поданим у вигляді рядка '1111111111111111111111111111111111111111111111111111111111111111'.

Він може бути модифікований для подання набагато більшого цілого числа, хоча він може бути не таким зручним, як "{0:b}".format()або bin().


@GarethDavidson, яка це версія? Якщо це явно сказано, це може бути корисним у майбутньому при його гугленні.
— Вовк

Думаю, це була версія 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 - ширина двійкового рядка.



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"?
— dietbacon

якщо ви хочете побачити, що 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 , Мартіна Тома . та Мартійн Пітерс.


6
str.format()просто відформатувати одне значення є надмірним. Ідіть прямо до format()функції: format(n, 'b'). Не потрібно розбирати заповнювач місця та порівнювати його з таким аргументом.
— Martijn Pieters

10

В якості попередніх відповідей в основному використовується формат (), ось реалізація f-string.

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'


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



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

3

ось просте рішення, використовуючи fucntion divmod (), який повертає нагадування та результат поділу без дробу.

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin

Потреби налагодження. Виклик 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']

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')

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

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")

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 to binary. Ви надаєте двійковий код до 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), ви отримаєте те, що очікуєте?
— Андреас Магнуссон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.