msgspec icon indicating copy to clipboard operation
msgspec copied to clipboard

Straightforward way to iterate over struct field names and values similar to `dict.items()`

Open jnrbsn opened this issue 7 months ago • 1 comments

Description

I looked through your docs and couldn't find a straightforward way to iterate over struct field names and values similar to dict.items(). Obviously, there are various ways I can do this...

# (1) using fields()
for field in fields(s):
    name = field.name
    value = getattr(s, name)
    ...

# (2) cache fields ahead of time (way faster if you're re-using)
mystruct_fields = fields(MyStruct)
for field in mystruct_fields:
    name = field.name
    value = getattr(s, name)
    ...

# (3) using asdict().items()
for name, value in asdict(s).items():
    ...

# (4) using zip(fields(), astuple())
for field, value in zip(fields(s), astuple(s)):
    ...

# (5) same as (4), but cache the fields (fastest)
mystruct_fields = fields(MyStruct)
for field, value in zip(mystruct_fields, astuple(s)):
    ...

(5) is the fastest, but I feel like (3) is the most straightforward. Why not have a built-in function similar to dict.items() that does this? That way I can do something like this:

from msgspec.structs import items

for field, value in items(s):
    ...

Feel free to call it something else. I hate naming things.

jnrbsn avatar Apr 05 '25 17:04 jnrbsn

Side note: My examples using zip() make me a little nervous because I don't know if the ordering is guaranteed to be consistent between fields() and astuple(). Is it?

jnrbsn avatar Apr 05 '25 17:04 jnrbsn