Python 列表理解未分配给新数组
Python list comprehension not assigned to new array
我是 python 的新手,我想在 class 构造函数中解析一些数据。输入是一个带有十六进制分隔符的字符串:
b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
然后我想拆分这个字符串,对于每个拆分我想将结果解码为 utf-8 以丢弃我不感兴趣的其他字符:
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frames = data.split(b'\x02')
utf_frames = [frame.decode('utf-8') for frame in frames]
print(utf_frames)
# Prints:
# ['\x01', 'A610088906\x03', 'R1138\x03', 'C\x03', 'B610089002\x03', 'SG20L71800\x03', 'MGFS4470\x03', 'm\x03', 'I47\x03\x04']
如果我改为像这样写我的列表理解,我会看到打印出的解码值:
[print(frame.decode('utf-8')) for frame in frames]
A610088906
R1138
C
B610089002
SG20L71800
MGFS4470
m
I47
我使用的是 3.8.5 版本。
我做错了什么?
编辑
为清楚起见,这就是我想要实现的(但我不想每次都必须找到一帧时解码所有条目)
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frame_identifier = 'M'
frame = [frame for frame in data.split(b'\x02') if frame.decode('utf-8').startswith(frame_identifier)][0].decode('utf-8')[1:]
print(frame)
# GFS4470
解决方案
多亏了答案,我发现了悬挂的 \x03
,自从我解码为 utf-8 字符串后,它就不可见了。这现在有效:
frame_identifier = 'M'
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
utf_frames = [frame.decode('utf-8') for frame in data.split(b'\x02')]
frame = [frame for frame in self.utf_frames if frame.startswith(frame_identifier)][0][1:-1]
print(type(frame), frame, str(frame), repr(frame))
# <class 'str'> GFS4470 GFS4470 'GFS4470'
让我们回到您的第一个编码示例并稍微修改它以查看发生了什么:
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frames = data.split(b'\x02')
utf_frames = [frame.decode('utf-8') for frame in frames]
print(utf_frames)
for f in utf_frames:
print(type(f), f, str(f), repr(f))
打印:
['\x01', 'A610088906\x03', 'R1138\x03', 'C\x03', 'B610089002\x03', 'SG20L71800\x03', 'MGFS4470\x03', 'm\x03', 'I47\x03\x04']
<class 'str'> '\x01'
<class 'str'> A610088906 A610088906 'A610088906\x03'
<class 'str'> R1138 R1138 'R1138\x03'
<class 'str'> C C 'C\x03'
<class 'str'> B610089002 B610089002 'B610089002\x03'
<class 'str'> SG20L71800 SG20L71800 'SG20L71800\x03'
<class 'str'> MGFS4470 MGFS4470 'MGFS4470\x03'
<class 'str'> m m 'm\x03'
<class 'str'> I47 I47 'I47\x03\x04'
因此,当您打印解码帧的列表而不是单独打印每个帧时,Python 选择对每个列表元素调用 repr
方法而不是 str
方法。
Python 没有 print
列表的内容,只有 print
它的结构。在使用列表理解的情况下,python print
列表的每个元素。所以控制字符没有出现在控制台中。
我是 python 的新手,我想在 class 构造函数中解析一些数据。输入是一个带有十六进制分隔符的字符串:
b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
然后我想拆分这个字符串,对于每个拆分我想将结果解码为 utf-8 以丢弃我不感兴趣的其他字符:
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frames = data.split(b'\x02')
utf_frames = [frame.decode('utf-8') for frame in frames]
print(utf_frames)
# Prints:
# ['\x01', 'A610088906\x03', 'R1138\x03', 'C\x03', 'B610089002\x03', 'SG20L71800\x03', 'MGFS4470\x03', 'm\x03', 'I47\x03\x04']
如果我改为像这样写我的列表理解,我会看到打印出的解码值:
[print(frame.decode('utf-8')) for frame in frames]
A610088906
R1138
C
B610089002
SG20L71800
MGFS4470
m
I47
我使用的是 3.8.5 版本。
我做错了什么?
编辑
为清楚起见,这就是我想要实现的(但我不想每次都必须找到一帧时解码所有条目)
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frame_identifier = 'M'
frame = [frame for frame in data.split(b'\x02') if frame.decode('utf-8').startswith(frame_identifier)][0].decode('utf-8')[1:]
print(frame)
# GFS4470
解决方案
多亏了答案,我发现了悬挂的 \x03
,自从我解码为 utf-8 字符串后,它就不可见了。这现在有效:
frame_identifier = 'M'
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
utf_frames = [frame.decode('utf-8') for frame in data.split(b'\x02')]
frame = [frame for frame in self.utf_frames if frame.startswith(frame_identifier)][0][1:-1]
print(type(frame), frame, str(frame), repr(frame))
# <class 'str'> GFS4470 GFS4470 'GFS4470'
让我们回到您的第一个编码示例并稍微修改它以查看发生了什么:
data = b'\x01\x02A610088906\x03\x02R1138\x03\x02C\x03\x02B610089002\x03\x02SG20L71800\x03\x02MGFS4470\x03\x02m\x03\x02I47\x03\x04'
frames = data.split(b'\x02')
utf_frames = [frame.decode('utf-8') for frame in frames]
print(utf_frames)
for f in utf_frames:
print(type(f), f, str(f), repr(f))
打印:
['\x01', 'A610088906\x03', 'R1138\x03', 'C\x03', 'B610089002\x03', 'SG20L71800\x03', 'MGFS4470\x03', 'm\x03', 'I47\x03\x04']
<class 'str'> '\x01'
<class 'str'> A610088906 A610088906 'A610088906\x03'
<class 'str'> R1138 R1138 'R1138\x03'
<class 'str'> C C 'C\x03'
<class 'str'> B610089002 B610089002 'B610089002\x03'
<class 'str'> SG20L71800 SG20L71800 'SG20L71800\x03'
<class 'str'> MGFS4470 MGFS4470 'MGFS4470\x03'
<class 'str'> m m 'm\x03'
<class 'str'> I47 I47 'I47\x03\x04'
因此,当您打印解码帧的列表而不是单独打印每个帧时,Python 选择对每个列表元素调用 repr
方法而不是 str
方法。
Python 没有 print
列表的内容,只有 print
它的结构。在使用列表理解的情况下,python print
列表的每个元素。所以控制字符没有出现在控制台中。