python編程中用到通訊,也自然需要用到字符串轉list功能,試過了很多方法均不理想,最後不得已用了神通廣大的eval()
具體如下:
str0 = b'[[0], [486.13334690553745, 473.83448697068405, 7.678963807368689]],[[1], [504.08351648351646], 256.98362637362635],[[2], []],[[3], []]'
要將這一個字符串,轉為list或ndarray,維度不定,長度也不定,裡面內容不是int,而是float。
網上找到很多方法,但都有局限,最後要麼是維度限制,要麼是長度限制,要麼是int限制,要麼就不能識別方括號。
最後一句話搞定:
temp1 = eval(str1)
運行結果:
([[0], [486.13334690553745, 473.83448697068405, 7.678963807368689]], [[1], [504.08351648351646], 256.98362637362635], [[2], []], [[3], []])
看不出來轉換情況哈,那麼打斷點,看temp1這個變量的數據結構,見下圖
最深層的數據類型是float,結構層次也OK。結果滿意。
為什麼又說是不得已才用eval()呢,因為這個函數太神奇了,它是運行括號中的內容,也就是將其當作一個表達式來運行的,這裡面就有一個隱患,如果通訊的對方是一個惡意程序,將惡意代碼隱藏到通訊內容中,那麼eval的運行結果是不可知的。
解決方法也有,對於我的這個通訊內容,用到了0到9的數字,空格,小數點,逗號,方括號,那麼我就可以將除了這些的其他所有符號,英文字母都去除,以去除隱患。
使用正則表達式,全代碼如下:
import re
str0 = b'[[0], [486.13334690553745, 473.83448697068405, 7.678963807368689]],[[1], [504.08351648351646], 256.98362637362635],[[2], []],[[3], []]'
str0 = str0.decode('utf-8') # 去除前面那個b
str1 = re.sub('([^\u0030-\u0039\u005b\]\u002c\u002e])', '', str0)
temp1 = eval(str1)
print(temp1)
在print這一句打斷點,debug運行,可以看到temp1的內容,和之前是一樣的。
下面對正則表達式說明一下:
re.sub('([^\u0030-\u0039\u005b\]\u002c\u002e])', '', str0)
sub表示提取子集
\u0030-\u0039表示ASCII碼中30到39這一段,也就是數字0~9
\u005b表示左方括號 [
而右方括號不能這樣表示,需要轉義,即]
\u002c是逗號 ,
\u002e是小數點 .