str.format()tylko sformatowanie jednej wartości to przesada. Idź prosto do format()funkcji : format(n, 'b'). Nie ma potrzeby analizowania symbolu zastępczego i dopasowania go do argumentu, przejdź od razu do samej operacji formatowania wartości. Używaj tylko str.format()wtedy, gdy musisz umieścić sformatowany wynik w dłuższym ciągu (np. Użyj go jako szablonu).
Martijn Pieters
29
@mike: Lub użyj specyfikacji formatowania. Dodaj liczbę cyfr prowadzących 0do ciągu formatującego: format(10, '016b')formatuje do 16 cyfr z wiodącymi zerami.
Martijn Pieters
W tym przypadku 0na "{0:b}"nie można spadła? To znaczy, w przypadku, gdy formatowana jest tylko jedna liczba, poprawne jest umieszczenie "{:b}", prawda?
tomasyany
1
zwykle używa się reprezentacji 4/8 / ... bitów:"{:08b}".format(37)
Sparkler
2
f „{37: b}” w Python3.7 lub nowszym.
DA
471
Jeśli szukasz bin()jako odpowiednika hex(), został dodany w Pythonie 2.6.
Zauważ też, że jest to szybsze str(bin(i))[2:](0,369s dla 1000000opsów) niż "{0:b}".format(i)(0,721s dla 1000000opsów)
mVChr 30.10.13
64
@mVChr, jeśli ktoś konwertuje liczby na reprezentację binarną ASCII, naprawdę mam nadzieję, że prędkość nie ma znaczenia.
Nick T
29
@mVChr: i tak str.format()jest niewłaściwym narzędziem, którego byś użył format(i, 'b'). Weź jednak pod uwagę, że daje to również opcje dopełniania i wyrównania; format(i, '016b')sformatować do 16-bitowej liczby binarnej z wypełnieniem zerowym. Aby to samo bin()zrobić, musisz dodać str.zfill()połączenie: bin(i)[2:].zfill(16)(nie musisz dzwonić str()!). format()Czytelność i elastyczność (dynamiczne formatowanie jest znacznie trudniejsze bin()) to świetne kompromisy, nie optymalizuj pod kątem wydajności, chyba że musisz, do tego czasu zoptymalizuj pod kątem łatwości konserwacji.
Martijn Pieters
Co oznacza [2:]?
zero_cool
4
Oczywiście w Pythonie 3.6+ możesz teraz używać f"{37:b}".
Luke Davis
63
Python rzeczywiście robi coś już zbudowany w do tego, zdolność do czynności takich jak '{0:b}'.format(42), co daje wzór bitowy (w sznurku) do 42lub 101010.
W przypadku bardziej ogólnej filozofii żaden język ani biblioteka nie da swojej bazie użytkowników wszystkiego , czego pragną. Jeśli pracujesz w środowisku, które nie zapewnia dokładnie tego, czego potrzebujesz, powinieneś zbierać fragmenty kodu w miarę rozwoju, aby mieć pewność, że nigdy nie będziesz musiał pisać tego samego dwa razy. Takich jak na przykład pseudo-kod:
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
który zbuduje ciąg binarny na podstawie wartości dziesiętnej. Wystarczy pamiętać, że to generic trochę pseudo-kodu, który może nie być najbardziej skuteczny sposób to zrobić chociaż, z iteracji wydają się być zaproponowanie, nie będzie dużej różnicy. To naprawdę jest tylko wskazówką, jak można to zrobić.
Ogólna idea polega na użyciu kodu z (w kolejności preferencji):
język lub wbudowane biblioteki.
biblioteki stron trzecich z odpowiednimi licencjami.
twoja własna kolekcja.
coś nowego, co musisz napisać (i zapisać we własnej kolekcji na później).
Kilka dobrych rad w tej odpowiedzi. Szkoda tylko, że kod jest niepotrzebnie wolny. Proponujesz algo O (N ^ 2) tam, gdzie zrobiłby to O (N). Problematyczna część znajduje się w wierszach s = "1" + si s = "0" + s. Każda z nich tworzy niepotrzebną kopię s. Zamiast tego powinieneś odwrócić ciąg bezpośrednio przed jego zwróceniem.
Andreas Magnusson
@Andreas, to, co zaproponowałem, to użycie '{0:b}'.format(42), metoda powolna była po prostu przykładem tego, jak to zrobić ogólnie, którym może być O (n ^ 2) w zależności od używanego języka. Wygląda tylko jak Python, ponieważ Python jest idealnym językiem pseudokodu, więc zmienię to, aby było jasne.
paxdiablo
Właściwie byłby to dość ezoteryczny język, w którym s = "1" + snie było O (N), gdy sjest typem łańcucha. Może język, w którym wszystkie ciągi są przechowywane wstecz lub każdy znak jest węzłem na liście połączonej? Dla każdego typowego języka ciąg znaków jest w zasadzie tablicą znaków. W takim przypadku prefiks ciągu wymaga wykonania kopii, w jaki sposób zamierzasz umieścić znak przed innymi znakami?
Andreas Magnusson
Mogę łatwo wyobrazić sobie typ łańcucha, który składa się z bloku pamięci, w którym łańcuch jest odpowiednio wyjustowany w tym bloku, oraz przesunięcie względem jego początkowego znaku. Aby poprzedzić znak, należy po prostu zmniejszyć przesunięcie i zapisać tam znak. Tak, byłoby to ezoteryczne, ale nie ma dla mnie sensu spieranie się o możliwe problemy w świecie rzeczywistym z odrobiną pseudo-kodu, zwłaszcza, że prawdopodobnie nie będziesz mieć więcej niż kilkudziesięciu bitów / iteracji. Nawet bardzo zły typ bąbelków jest odpowiedni, jeśli twój rozmiar danych jest mały :-) W każdym razie dodam notatkę o wydajności.
paxdiablo
Jasne, jeśli wydajność jest ważna, prawdopodobnie nie wybrałbyś Pythona na początek. Jednak z mojego doświadczenia wynika, że dość często kod, który został naiwnie napisany za pomocą algo O (N²) i przetestowany z małym zestawem danych, szybko przyzwyczaja się do znacznie większego zestawu danych, ponieważ „wydaje się, że działa”. Nagle masz kod, którego uruchomienie zajmuje wiele godzin, a gdy jest naprawiony, może zająć tylko kilka sekund. Algony O (N²) są podstępne, ponieważ wydają się działać przez jakiś czas, ale kiedy twoje dane się skalują, nie robią tego, a do tego czasu facet, który je napisał, zrezygnował i nikt nie wie, dlaczego wszystko trwa wiecznie.
Andreas Magnusson
41
Jeśli chcesz reprezentację tekstową bez prefiksu 0b, możesz użyć tego:
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)
Lub po prostu użyj format(integer, 'b'). bin()jest narzędziem do debugowania, specjalnie ukierunkowanym na tworzenie binarnej składni całkowitej literału Pythona , format()przeznaczonym do tworzenia określonych formatów.
Martijn Pieters
1
@MartijnPieters Bardzo dziękuję za wzmiankę o tym. Dostosowałem swoje rozwiązanie. Skąd wiesz, że bin()jest to narzędzie do debugowania, którego celem jest tworzenie binarnej składni całkowitej literału Pythona? Nie mogłem tego znaleźć w dokumentacji.
Martin Thoma,
2
Z dokumentacji: Wynikiem jest prawidłowe wyrażenie w języku Python . Jego celem jest stworzenie wyrażenia w języku Python, a nie reprezentacje użytkowników końcowych. To samo dotyczy oct()i hex().
Martijn Pieters
4
Więcej alternatyw: jeśli zamierzasz uczynić szerokość dynamiczną, zamiast str.zfill()możesz użyć str.format()lub format()z dynamicznym drugim argumentem: '{0:0{1}b}'.format(x, n)lub format(b, '0{}b'.format(n)).
Martijn Pieters
@MartijnPieters Wow, bardzo dziękuję za ten wkład! Nie wiedziałem, że było to możliwe dzięki formatowi. Myślę jednak, że moja obecna odpowiedź zfilljest łatwiejsza do odczytania i zrozumienia niż dynamiczny drugi argument, więc zachowam to.
Martin Thoma,
37
Jako odniesienie:
def toBinary(n):return''.join(str(1& int(n)>> i)for i in range(64)[::-1])
Ta funkcja może konwertować dodatnią liczbę całkowitą tak dużą, jak 18446744073709551615, reprezentowaną przez ciąg '1111111111111111111111111111111111111111111111111111111111111111'.
Można go zmodyfikować, aby obsługiwał znacznie większą liczbę całkowitą, chociaż może nie być tak przydatny jak "{0:b}".format()lub bin().
która zwraca „” dla 0. Czy normalna reprezentacja dla 0 nie byłaby „0”?
dietbacon
jeśli chce zobaczyć, że 0 :), można zastąpić ''z '0', ale doda cyfrę 0 dla dowolnej liczby.
Aziz Alto
11
Podsumowanie alternatyw:
n=42assert"-101010"== format(-n,'b')assert"-101010"=="{0:b}".format(-n)assert"-101010"==(lambda x: x >=0and 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.
str.format()tylko sformatowanie jednej wartości to przesada. Idź prosto do format()funkcji: format(n, 'b'). Nie trzeba analizować symbolu zastępczego i dopasowywać go do argumentu w ten sposób.
Martijn Pieters
10
Ponieważ w poprzednich odpowiedziach najczęściej używany był format (), oto implementacja ciągu f-string.
Używając numpy pack / unpackbits, są twoimi najlepszymi przyjaciółmi.
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)
Pytanie dotyczy reprezentacji ciągu . Mimo to stało się to tym, czego szukałem, nie przechodząc najpierw przez sznurek! :)
Tom Hale
Doco mówi: rozpakowuje elementy uint8tablicy do tablicy wyjścia binarnego wycenione. Tak dobre dla wartości do 255.
Tom Hale
5
Dla tych z nas, którzy muszą konwertować podpisane liczby całkowite (zakres -2 ** (cyfry-1) na 2 ** (cyfry-1) -1) na ciągi binarne dopełniające 2, działa to:
Druga wersja zdecydowanie nie jest szybsza, ponieważ zamiast O (N) powstaje coś w rodzaju algorytmu O (N ^ 2). Widziałem takie rzeczy, jak zabijanie aplikacji (pod względem wydajności), ponieważ deweloper pomyślał, że wykonanie dodatkowego przejścia na końcu było wolniejsze niż wykonanie dodatkowych czynności w pierwszej pętli. Raz naprawiony skrócił czas pracy z dni do sekund.
Oto kod, który właśnie zaimplementowałem. To nie jest metoda, ale możesz jej użyć jako funkcji gotowej do użycia !
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
Oto jeszcze jeden sposób, używając zwykłej matematyki, bez pętli, tylko rekurencja. (Trywialny przypadek 0 nic nie zwraca).
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']
Kalkulator ze wszystkimi niezbędnymi funkcjami dla DEC, BIN, HEX: (stworzony i przetestowany w Pythonie 3.5)
Możesz zmienić wejściowe numery testowe i uzyskać przekonwertowane.
# CONVERTER: DEC / BIN / HEXdef 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)## PRINTINGprint('------- 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')
Odpowiedzi:
Metoda formatu ciągu znaków w Pythonie może przyjmować specyfikację formatu.
Sformatuj dokumentację specyfikacji dla Python 2
Sformatuj dokumentację specyfikacji dla Python 3
źródło
str.format()
tylko sformatowanie jednej wartości to przesada. Idź prosto doformat()
funkcji :format(n, 'b')
. Nie ma potrzeby analizowania symbolu zastępczego i dopasowania go do argumentu, przejdź od razu do samej operacji formatowania wartości. Używaj tylkostr.format()
wtedy, gdy musisz umieścić sformatowany wynik w dłuższym ciągu (np. Użyj go jako szablonu).0
do ciągu formatującego:format(10, '016b')
formatuje do 16 cyfr z wiodącymi zerami.0
na"{0:b}"
nie można spadła? To znaczy, w przypadku, gdy formatowana jest tylko jedna liczba, poprawne jest umieszczenie"{:b}"
, prawda?"{:08b}".format(37)
Jeśli szukasz
bin()
jako odpowiednikahex()
, został dodany w Pythonie 2.6.Przykład:
źródło
str(bin(i))[2:]
(0,369s dla 1000000opsów) niż"{0:b}".format(i)
(0,721s dla 1000000opsów)str.format()
jest niewłaściwym narzędziem, którego byś użyłformat(i, 'b')
. Weź jednak pod uwagę, że daje to również opcje dopełniania i wyrównania;format(i, '016b')
sformatować do 16-bitowej liczby binarnej z wypełnieniem zerowym. Aby to samobin()
zrobić, musisz dodaćstr.zfill()
połączenie:bin(i)[2:].zfill(16)
(nie musisz dzwonićstr()
!).format()
Czytelność i elastyczność (dynamiczne formatowanie jest znacznie trudniejszebin()
) to świetne kompromisy, nie optymalizuj pod kątem wydajności, chyba że musisz, do tego czasu zoptymalizuj pod kątem łatwości konserwacji.f"{37:b}"
.Python rzeczywiście robi coś już zbudowany w do tego, zdolność do czynności takich jak
'{0:b}'.format(42)
, co daje wzór bitowy (w sznurku) do42
lub101010
.W przypadku bardziej ogólnej filozofii żaden język ani biblioteka nie da swojej bazie użytkowników wszystkiego , czego pragną. Jeśli pracujesz w środowisku, które nie zapewnia dokładnie tego, czego potrzebujesz, powinieneś zbierać fragmenty kodu w miarę rozwoju, aby mieć pewność, że nigdy nie będziesz musiał pisać tego samego dwa razy. Takich jak na przykład pseudo-kod:
który zbuduje ciąg binarny na podstawie wartości dziesiętnej. Wystarczy pamiętać, że to generic trochę pseudo-kodu, który może nie być najbardziej skuteczny sposób to zrobić chociaż, z iteracji wydają się być zaproponowanie, nie będzie dużej różnicy. To naprawdę jest tylko wskazówką, jak można to zrobić.
Ogólna idea polega na użyciu kodu z (w kolejności preferencji):
źródło
s = "1" + s
is = "0" + s
. Każda z nich tworzy niepotrzebną kopię s. Zamiast tego powinieneś odwrócić ciąg bezpośrednio przed jego zwróceniem.'{0:b}'.format(42)
, metoda powolna była po prostu przykładem tego, jak to zrobić ogólnie, którym może być O (n ^ 2) w zależności od używanego języka. Wygląda tylko jak Python, ponieważ Python jest idealnym językiem pseudokodu, więc zmienię to, aby było jasne.s = "1" + s
nie było O (N), gdys
jest typem łańcucha. Może język, w którym wszystkie ciągi są przechowywane wstecz lub każdy znak jest węzłem na liście połączonej? Dla każdego typowego języka ciąg znaków jest w zasadzie tablicą znaków. W takim przypadku prefiks ciągu wymaga wykonania kopii, w jaki sposób zamierzasz umieścić znak przed innymi znakami?Jeśli chcesz reprezentację tekstową bez prefiksu 0b, możesz użyć tego:
Kiedy chcesz reprezentacji n-bitowej:
Alternatywnie, jeśli wolisz mieć funkcję:
źródło
format(integer, 'b')
.bin()
jest narzędziem do debugowania, specjalnie ukierunkowanym na tworzenie binarnej składni całkowitej literału Pythona ,format()
przeznaczonym do tworzenia określonych formatów.bin()
jest to narzędzie do debugowania, którego celem jest tworzenie binarnej składni całkowitej literału Pythona? Nie mogłem tego znaleźć w dokumentacji.oct()
ihex()
.str.zfill()
możesz użyćstr.format()
lubformat()
z dynamicznym drugim argumentem:'{0:0{1}b}'.format(x, n)
lubformat(b, '0{}b'.format(n))
.zfill
jest łatwiejsza do odczytania i zrozumienia niż dynamiczny drugi argument, więc zachowam to.Jako odniesienie:
Ta funkcja może konwertować dodatnią liczbę całkowitą tak dużą, jak
18446744073709551615
, reprezentowaną przez ciąg'1111111111111111111111111111111111111111111111111111111111111111'
.Można go zmodyfikować, aby obsługiwał znacznie większą liczbę całkowitą, chociaż może nie być tak przydatny jak
"{0:b}".format()
lubbin()
.źródło
Prostym sposobem na to jest użycie formatu ciągu, zobacz tę stronę .
A jeśli chcesz mieć stałą długość ciągu binarnego, możesz użyć tego:
Jeśli wymagane jest uzupełnienie dwóch, można użyć następującego wiersza:
gdzie n jest szerokością ciągu binarnego.
źródło
To dotyczy Pythona 3 i zachowuje wiodące zera!
źródło
jednowarstwowy z lambda :
test:
EDYCJA :
ale wtedy :(
w porównaniu do
źródło
''
z'0'
, ale doda cyfrę 0 dla dowolnej liczby.Podsumowanie alternatyw:
Współautorzy to John Fouhy , Tung Nguyen , mVChr , Martin Thoma . i Martijn Pieters.
źródło
str.format()
tylko sformatowanie jednej wartości to przesada. Idź prosto doformat()
funkcji:format(n, 'b')
. Nie trzeba analizować symbolu zastępczego i dopasowywać go do argumentu w ten sposób.Ponieważ w poprzednich odpowiedziach najczęściej używany był format (), oto implementacja ciągu f-string.
Wynik:
Dla wygody tutaj jest link do docs docs sformatowanych literałów łańcuchowych: https://docs.python.org/3/reference/lexical_analysis.html#f-strings .
źródło
źródło
Używając numpy pack / unpackbits, są twoimi najlepszymi przyjaciółmi.
źródło
uint8
tablicy do tablicy wyjścia binarnego wycenione. Tak dobre dla wartości do 255.Dla tych z nas, którzy muszą konwertować podpisane liczby całkowite (zakres -2 ** (cyfry-1) na 2 ** (cyfry-1) -1) na ciągi binarne dopełniające 2, działa to:
Daje to:
źródło
Chyba, że nie rozumiem, co masz na myśli przez ciąg binarny, myślę, że moduł, którego szukasz, to struct
źródło
Jeszcze inne rozwiązanie z innym algorytmem, wykorzystujące operatory bitowe.
Szybsza wersja bez odwracania łańcucha.
źródło
wynik:
źródło
możesz to zrobić:
lub:
źródło
Oto kod, który właśnie zaimplementowałem. To nie jest metoda, ale możesz jej użyć jako funkcji gotowej do użycia !
źródło
oto proste rozwiązanie wykorzystujące funkcję divmod (), która zwraca przypomnienie i wynik podziału bez ułamka.
źródło
dectobin(10)
spowodowało „0101”źródło
numpy.binary_repr(num, width=None)
Przykłady z linku do dokumentacji powyżej:
źródło
Nieco podobne rozwiązanie
źródło
Oto jeszcze jeden sposób, używając zwykłej matematyki, bez pętli, tylko rekurencja. (Trywialny przypadek 0 nic nie zwraca).
źródło
Kalkulator ze wszystkimi niezbędnymi funkcjami dla DEC, BIN, HEX: (stworzony i przetestowany w Pythonie 3.5)
Możesz zmienić wejściowe numery testowe i uzyskać przekonwertowane.
źródło
źródło
Jeśli chcesz zrezygnować z „czystego” Pythona, ale zyskać dużą siłę ognia, jest Sage - przykład tutaj :
Zauważysz, że zwraca jako ciąg, więc aby użyć go jako liczby, którą chcesz zrobić
źródło
źródło
Znalazłem metodę używającą operacji macierzowej do konwersji dziesiętnej na binarną.
E
to wejściowe dane dziesiętne,M
to porządki binarne.bindata
to wyjściowe dane binarne, które mają format 1 na M macierzy binarnej.źródło
Oto prosty konwerter binarny na dziesiętny, który ciągle się zapętla
źródło
To jest moja odpowiedź, działa dobrze ..!
źródło
0
? Np.binary(0)
Czy dostaniesz to, czego oczekujesz?