遍历字典(哈希表)并打包成结构

时间:2019-12-07 01:51:38

标签: arrays python-3.x dictionary struct byte

我正在用Python 3编写程序,我想做的一项任务是获取字典并通过网络(使用UDP)发送它。但是,由于我无法先通过UDP发送字典,而不先将其转换为原始字节数据,所以我决定使用struct库并将键和值打包到bytearray中。

我想要的结构格式是这样:

struct format

我决定使用struct.pack_into()函数,因为我想遍历字典中的每个(key, value)并将它们打包。

到目前为止,这是我的代码,并带有示例字典:

import struct
my_dict = {2: 4, 3: 1}  # I have 4 entries in this example.

# The length of my_dict is 2; multiply by 2 to get the desired value of 4.
num_entries = 2 * len(my_dict.keys())

# I need to pack "num_entries" itself, then each (key, value) entry.
# I multiply this total by 2 at the end because I need each value to be
# 2 bytes.
# E.g. if num_entries is 2, then I need space to pack the "2", then
# key_one, value_one, key_two, value_two. That's 10 bytes total.
b = bytearray((1 + num_entries) * 2)

for i, (key, value) in enumerate(my_dict.items(), start=1):
     struct.pack_into('!2H', b, i, key, value)  # Use 'i' as the offset.
     print(b)

# Now prepend num_entries (2, in this case) to the top of the struct.
struct.pack_into('!H', b, 0, num_entries)

# Print the final struct.
print(b)

我想要的最终结构输出是这样:

bytearray(b'\x00\x02\x00\x02\x00\x04\x00\x03\x00\x01')

但是我得到了:

struct at this point in the loop: bytearray(b'\x00\x00\x02\x00\x04\x00\x00\x00\x00\x00')
struct at this point in the loop: bytearray(b'\x00\x00\x00\x03\x00\x01\x00\x00\x00\x00')
bytearray(b'\x00\x02\x00\x03\x00\x01\x00\x00\x00\x00')  # The final bytearray. key=2, value=4 is not present!

似乎我没有在正确的位置打包到结构中。我想从key获取每个valuemy_dict并打包,然后移至下一个keyvalue并打包在下一个两个字节以上(因此我使用enumerate()来保持迭代器),依此类推。请参考上图。但是似乎字节被覆盖了。

我在做什么错了,我该如何纠正?

1 个答案:

答案 0 :(得分:0)

我最终找到了另一种解决方案。我只是使用struct.pack_into()的{​​{1}}方法,而不是使用enumerate()extend(),就像这样:

bytearray()

上面给出了我想要的输出:

import struct
my_dict = {2: 4, 3: 1}  # I have 2 entries (keys) in this example.
num_entries = len(my_dict.keys())
b = bytearray()

b.extend(struct.pack('!H', num_entries))  # Prepend the number of entries.

for key, value in my_dict.items():
    b.extend(struct.pack('!2H', key, value))

# Print the final bytearray.
print(b)