程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python字符串轉list,多維度,支持float,並保持原數據結構

編輯:Python

問題

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是小數點 .


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved