簡體   English   中英

使用Python將二進制字符串轉換為整數列表

[英]Convert binary string to list of integers using Python

我是Python的新手。 這是我想要做的:

  1. 將長二進制字符串切成3位長的塊。
  2. 將每個“塊”存儲到名為row的列表中。
  3. 將每個二進制塊轉換為數字(0-7)。
  4. 將轉換后的數字列表存儲到名為numbers的新列表中。

這是我到目前為止:

def traverse(R):
        x = 0
        while x < (len(R) - 3):
            row = R[x] + R[x+1] + R[x+2]
            ???

謝謝你的幫助! 非常感謝。

這樣的事情應該這樣做:

s = "110101001"
numbers = [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
print numbers

輸出是:

[6, 5, 1]

首先逐步打破這個問題:

>>> range(0, len(s), 3)
[0, 3, 6]

range()函數在步驟3中生成一個從0開始的整數列表,小於最大len(s)

>>> [s[i:i+3] for i in range(0, len(s), 3)]
["110", "101", "001"]

這是一個列表推導 ,它評估上述范圍內每個i s[i:i+3] s[i:i+3]是一個選擇子串的切片 最后:

>>> [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
[6, 5, 1]

int(..., 2)函數從二進制(基數2,第二個參數)轉換為整數。

請注意,上述代碼可能無法正確處理錯誤條件,例如輸入字符串長度不是3個字符的倍數。

我假設“二進制字符串”實際上是指一個正常的字符串(即文本),其項目都是“0”或“1”。

所以對於第1點和第2點,

row = [thestring[i:i+3] for i in xrange(0, len(thestring), 3)]

當然,如果len(thestring)不是3的精確倍數,那么最后一項只有1或2個字符,這是不可避免的;-)。

對於第3點和第4點,我建議構建一個輔助臨時字典並存儲它:

aux = {}
for x in range(8):
  s = format(x, 'b')
  aux[s] = x
  aux[('00'+s)[-3:]] = x

所以第3點和第4點變為:

numbers = [aux[x] for x in row]

這個字典查找應該比快速轉換每個條目快得多。

編輯 :有人建議我解釋為什么我為x每個值兩個條目進入aux 關鍵是s可以是1到3個字符的任意長度,對於短的長度,我確實需要兩個條目 - 一個用s作為它(因為我提到row中的最后一項可能短於3 ...),和一個與它的左填充為3的長度的0秒。

子表達式('00'+s)[-3:]通過取最后3個字符(即[-3:]切片部分)來計算“左邊填充'0'到3的長度”通過在s的左邊放置零獲得的字符串(即'00'+s部分)。 如果s已經是3個字符長,那么整個子表達式將等於s因此對aux那個條目的賦值是無用的但是無害的,所以我發現更簡單甚至不打擾檢查(在if len(s)<3:之前加上if len(s)<3:將是味道也很好;-)。

還有其他方法(例如,如果需要再次格式化x ),但這不是代碼的關鍵(它只執行8次構建輔助“查找表”,畢竟;-),所以我沒有支付它足夠的注意力

...我也沒有進行單元測試,所以它在一個不起眼的角落里有一個錯誤。 你能看見它嗎...?

假設row'01'作為最后一個條目:在我的代碼上面已經構建了aux之后,那個密鑰將不會出現在aux1001出現,但這是很少的安慰;-)。 在上面的代碼中,我使用原始的s'1'和長度為3的填充版本'001' ,但是中間長度 - 兩個填充版本,oops,被忽略了;-)。

所以,這是一個正確的方法......:

aux = {}
for x in range(8):
  s = format(x, 'b')
  aux[s] = x
  while len(s) < 3:
    s = '0' + s
    aux[s] = x

......無疑更簡單,更明顯,但更重要的是,正確;-)。

如果您正在處理任何類型的原始數據,我想推薦優秀的bitstring模塊:

>>> import bitstring
>>> bits = bitstring.Bits('0b110101001')
>>> [b.uint for b in bits.cut(3)]
[6, 5, 1]

主頁的描述:

一個Python模塊,它使二進制數據的創建,操作和分析盡可能簡單和自然。

可以用整數,浮點數,十六進制,八進制,二進制,字節或文件構造Bitstrings。 它們也可以使用靈活的格式字符串創建和解釋。

可以使用簡單的方法或使用切片表示法對Bitstrings進行切片,連接,反轉,插入,覆蓋等操作。 它們也可以被讀取,搜索和替換,以及導航,類似於文件或流。

在內部,位數據有效地存儲在字節數組中,模塊已針對速度進行了優化,並且通過400多個單元測試提供了出色的代碼覆蓋率。

Greg和Alex的精彩回答! 列表理解和切片是如此pythonic! 對於短輸入字符串,我不打擾字典查找技巧,但如果輸入字符串更長,我會,以及使用gen-exps而不是list-comps,即:

row = list(thestring [i:i + 3] for x in xrange(0,len(thestring),3))

numbers = list(行中x的aux [x])

因為gen-exp表現更好。

這不會更容易:

(我想要一個包含整數29的變量的高3位數組)

首先格式化變量和數組

a =''

b = []

我從這個論壇中的一個非常好的例子中偷走了這個,它將整數29格式化為5位,位0到4,並將位串放入字符串變量“a”。 [編輯]需要將格式從0:5b更改為0:05b,以便在整數<7時填充零。

a ='{0:05b}'。格式(29)

看看你的字符串變量

一個

'11101'

將您的字符串拆分為數組

b [0:3] = a [0:3]

這正是我想要的。

b

['1','1','1']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM