распаковать структуру python в dict

struct.unpack распаковывает данные в кортеж. Есть ли эквивалент, который вместо этого будет хранить данные в dict?

В моей конкретной проблеме я имею дело с двоичным форматом фиксированной ширины. Я хочу иметь возможность одним махом распаковывать и сохранять значения в dict (в настоящее время я вручную просматриваю список и назначаю значения dict)


person Foo Bah    schedule 23.08.2011    source источник
comment
Я так не думаю. Но конструктор dict может принимать список или итератор пар (имя, значение) для инициализации. Это может помочь вам.   -  person Keith    schedule 23.08.2011
comment
Вас также может заинтересовать namedtuple, если вам не нужно изменять объект после его создания.   -  person kindall    schedule 23.08.2011
comment
Что вы ожидаете от ключей?   -  person FogleBird    schedule 23.08.2011


Ответы (3)


В документации 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...

person mtrw    schedule 23.08.2011
comment
Хех, наверное, надо было проверить веб-документ. Нет указаний на это в питоне help(struct) - person Foo Bah; 23.08.2011
comment
интересный ответ. я вижу, что это динамически сгенерированная функция, но почему _asdict() начинается с подчеркивания? - person wim; 23.08.2011
comment
Использование приватных методов - отличная идея. - person FogleBird; 24.08.2011
comment
@FogleBird - не уверен, что вы имеете в виду под частными методами. namedtuple._asdict() задокументировано здесь: python.org/doc/ /текущая/библиотека/. И я взял использование namedtuple._make() непосредственно из документации, указанной в ответе. Какова рекомендуемая передовая практика здесь? - person mtrw; 24.08.2011
comment
Пробелы после raymond сводят меня с ума от отладки кода. - person coanor; 06.02.2014
comment
Почему код не может работать под python3: TypeError: 'str' does not support the buffer interface? - person coanor; 06.02.2014
comment
Вы можете переписать пятую строку более кратко, как Student(*struct.unpack('<10sHHb', record))._asdict() - person Alastair Irvine; 20.11.2018
comment
это решение значительно медленнее, чем dict(zip(keys,struct.unpack(...))) - person Joran Beasley; 22.12.2019

Если вы используете версию 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
person PabloG    schedule 23.08.2011

Вы хотите что-то вроде этого?

keys = ['x', 'y', 'z']
values = struct.unpack('<III', data)
d = dict(zip(keys, values))
person FogleBird    schedule 23.08.2011
comment
это то, что я делаю сейчас. Я надеялся на что-то более гладкое - person Foo Bah; 23.08.2011
comment
это список, который просматривается (если только zip не делает что-то умное, что не связано с прохождением по списку). - person Foo Bah; 23.08.2011
comment
Я чувствую, что это решение в порядке, и оно уже лучше, чем возиться с collections.namedtuple - person wim; 23.08.2011
comment
кроме того, этот метод НАМНОГО быстрее, чем версия с именованным кортежем - person Joran Beasley; 22.12.2019