Python中的struct.unpack如何转换为字典?

8

struct.unpack将数据解包到元组中,是否有等效的方法可以将数据存储到字典中?

在我的特定问题中,我正在处理固定宽度的二进制格式。 我希望能够一次性地解包并将值存储在字典中(目前我手动遍历列表并分配字典值)。


2
我不这么认为。但是dict构造函数可以接受一个名称和值的列表或迭代器进行初始化。这可能会对你有所帮助。 - Keith
如果你在创建对象后不需要修改它,那么你可能也会对namedtuple感兴趣。 - kindall
2
你期望这些键是什么? - FogleBird
3个回答

11

如果您使用2.6或更新版本,可以像这样使用namedtuple + struct.pack/unpack:

import collections
import struct

Point = collections.namedtuple("Point", "x y z")

data = Point(x=1, y=2, z=3)

packed_data = struct.pack("hhh", *data)
data = Point(*struct.unpack("hhh", packed_data))

print data.x, data.y, data.z

9

你是否希望得到类似这样的东西?

keys = ['x', 'y', 'z']
values = struct.unpack('<III', data)
d = dict(zip(keys, values))

这是我现在正在做的。我希望有更流畅的东西。 - Foo Bah
这是一个正在遍历列表的过程(除非zip函数有一些不需要遍历列表的巧妙方法)。 - Foo Bah
3
我认为这个解决方案不错,已经比使用collections.namedtuple要更加简洁。 - wim
仅作为旁注,这种方法比命名元组版本快得多 - Joran Beasley

6

struct文档展示了一个例子,演示如何直接解压到namedtuple中。你可以结合使用namedtuple._asdict()来得到一个非常有用的结果:

>>> import struct
>>> from collections import namedtuple
>>> record = 'raymond   \x32\x12\x08\x01\x08'
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._asdict(Student._make(struct.unpack('<10sHHb', record)))
{'school': 264, 'gradelevel': 8, 'name': 'raymond   ', 'serialnum': 4658}
>>> 

如果有关系的话,请注意在Python 2.7中_asdict()返回一个OrderedDict...

3
有趣的答案。我看到它是一个动态生成的函数,但为什么_asdict()前面加了一个下划线? - wim
1
@FogleBird - 不确定你所说的私有方法指的是什么。namedtuple._asdict() 的文档在这里:http://www.python.org/doc//current/library/collections.html#collections.somenamedtuple._asdict。而我直接从答案中链接的文档中了解到了`namedtuple._make()`的用法。这里推荐最佳实践是什么? - mtrw
为什么代码在Python3下无法运行:“TypeError:'str'不支持缓冲区接口”? - coanor
1
你可以更简洁地重写第五行代码,如下:Student(*struct.unpack('<10sHHb', record))._asdict() - Alastair Irvine
1
这个解决方案比 dict(zip(keys,struct.unpack(...))) 慢得多。 - Joran Beasley
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接