Python 将字符串转换为定长列数组
如果我的问题在下面被淹没了,我需要向我的智能家居系统展示一个数组,这样我就可以逐个单元格地获取信息。
我正在使用以下代码从一个串口设备读取数据,这个设备会轮询我的家用暖通空调系统(大部分代码是从其他人的帖子中拷贝过来的):
import time
import serial
import StringIO
# configure the serial connections
ser = serial.Serial(
port='/dev/ttyS0',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
input=1
while 1 :
# Use static command to debug
input = "stats"
# Python 3 users
# input = input(">> ")
if input == 'exit':
ser.close()
exit()
else:
# send the character to the device
# (note that I happend a \r\n carriage return and line feed to the characters - this is requested by my device)
ser.write(input + '\r\n')
outputFCUData = ''
# let's wait one second before reading output (let's give device time to answer)
time.sleep(1)
while ser.inWaiting() > 0:
outputFCUData += ser.read(1)
if outputFCUData != '':
fcuArrayTemp = StringIO.StringIO(outputFCUData).read().splitlines()
fcuArrayTemp.pop(0)
fcuArrayTemp.pop(-1)
fcuArrayTemp.pop(-1)
fcuArrayTemp.pop(-1)
print fcuArrayTemp
exit()
如果我不进行任何格式化直接从设备获取数据,结果会是:
stats
101 ON 070F 070F Low Heat OK 0
102 ON 069F 069F Low Heat OK 0
103 ON 069F 069F Low Heat OK 0
104 ON 069F 070F Low Heat OK 0
105 OFF 072F 064F High Heat U5 0
OK
>
>
这时我会用 pop(0)
和 pop(-1)
的方法来去掉我不需要的行,只保留我想要的5行信息。对于好奇的人来说,第一列(例如“101”)是我的风机盘管名称,后面是状态、设定点、当前温度、风扇速度、模式(加热/制冷)、错误代码(例如105没有温控器,所以它有一个 U5错误
),最后一列是发送命令到设备时的任何错误——现在没有错误,所以显示“0”。
所以我想把这个输出转换成一个数组,这样我就可以通过 fcuStatus[i][j]
命令来提取单元格(i,j)中的信息。
我从代码中得到的结果是:
['101 ON 070F 070F Low Heat OK 0', '102 ON 069F 069F Low Heat OK 0', '103 ON 069F 069F Low Heat OK 0', '104 ON 069F 070F Low Heat OK 0', '105 OFF 072F 064F High Heat U5 0']
这是一个1行5列的列表。我认为我只需要从这个列表中读取元素,然后把它们添加到一个数组中。所以我添加了以下代码:
for element in fcuArrayTemp
parts = element.split(' ')
print parts
现在我的输出是:
['101', 'ON', '', '070F', '070F', '', 'Low', '', 'Heat', 'OK', '0']
['102', 'ON', '', '069F', '069F', '', 'Low', '', 'Heat', 'OK', '0']
['103', 'ON', '', '069F', '069F', '', 'Low', '', 'Heat', 'OK', '0']
['104', 'ON', '', '069F', '069F', '', 'Low', '', 'Heat', 'OK', '0']
['105', 'OFF', '072F', '064F', '', 'High', '', 'Heat', 'U5', '0']
这和我想要的差不多,只是因为我在单个空格上进行分割时,出现了一些额外的列,因为有双空格的存在。
我的代码写得很乱,我相信有更好的方法。有人能告诉我怎么把我在 outputFCUData
变量中收到的字符串信息转换成一个功能性数组,并且去掉多余的空格吗?列数总是8列,但随着风机盘管的增加,数组可能会扩展到128行以上。以上这些都是因为我不太懂,而不是因为我想遵循某些特定的规范——任何建议都非常欢迎。
编辑- 哇- Radio- 正好给了我我需要的东西- 谢谢你!
for element in fcuArrayTemp
parts = element.split()
print parts
所以最后一部分是,我该如何将这些整理好的列表创建成一个N行8列的矩阵?这在没有给append参数时会出错。把“element”加到要添加的项中(fcuArray.append(element))也没有解决问题。
fcuArray = []
for element in parts:
fcuArray = fcuArray.append()
print fcuArray
再次感谢
编辑:找到了一个适合我的解决方案——在这里分享给其他寻找类似东西的人。诀窍是将每一行从列表中添加到我的数组中,随着它们的生成:
fcuArray = []
for element in fcuArrayTemp
parts = element.split()
fcuArray.append(parts)
现在我可以通过请求行和位置来报告数组中的任何值。例如,要报告我数组中第三个风机盘管的名称,我会请求 fcuArray[3][0](也就是“print fcuArray[3][0]”,这会返回“104”。
这是我的完整代码:
import time
import serial
import StringIO
import pprint
# configure the serial connections
ser = serial.Serial(
port='/dev/ttyS0',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
input=1
while 1 :
# Use static command to debug
input = "stats"
# Python 3 users
# input = input(">> ")
if input == 'exit':
ser.close()
exit()
else:
# send the character to the device
# (note that I happend a \r\n carriage return and line feed to the characters - this is requested by my device)
ser.write(input + '\r\n')
outputFCUData = ''
# let's wait one second before reading output (let's give device time to answer)
time.sleep(1)
while ser.inWaiting() > 0:
outputFCUData += ser.read(1)
if outputFCUData != '':
fcuArrayTemp = StringIO.StringIO(outputFCUData).read().splitlines()
fcuArrayTemp.pop(0)
fcuArrayTemp.pop(-1)
fcuArrayTemp.pop(-1)
fcuArrayTemp.pop(-1)
fcuArray = []
for element in fcuArrayTemp:
parts = element.split()
fcuArray.append(parts)
print fcuArray
print fcuArray[3][0]
exit()
1 个回答
把 element.split(' ')
改成 element.split()
就可以去掉多余的列了。
>>> for element in fcuArrayTemp:
... print element.split()
...
['101', 'ON', '070F', '070F', 'Low', 'Heat', 'OK', '0']
['102', 'ON', '069F', '069F', 'Low', 'Heat', 'OK', '0']
['103', 'ON', '069F', '069F', 'Low', 'Heat', 'OK', '0']
['104', 'ON', '069F', '070F', 'Low', 'Heat', 'OK', '0']
['105', 'OFF', '072F', '064F', 'High', 'Heat', 'U5', '0']