Home > database >  Parse ImmutableMultiDict based on index at end of key strings
Parse ImmutableMultiDict based on index at end of key strings

Time:01-31

I receive a dict of tuples from a Flask/Jinja form:

request.form = (
    [
        ("music_style", "Bossa Nova"),
        ("song_title_1", "Águas De Março"),
        ("song_artists_1", "Elis Regina, Antônio Carlos Jobim"),
        ("song_title_2", "Mas, Que Nada!"),
        ("song_artists_2", "Jorge Ben Jor"),
        ("song_title_3", "Mais Que Nada"),
        ("song_artists_3", "Sergio Mendes & Brasil '66"),
    ]
)

I need it formatted where each indexed set is within it's own object:

post = {
        "music_style": "Bossa Nova"
            {
                "song_title": "Águas De Março",
                "song_artists": "Elis Regina, Antônio Carlos Jobim"
            },
            {
                "song_title": "Mas, Que Nada!",
                "song_artists": "Jorge Ben Jor"
            },
            {
                "song_title": "Mais Que Nada",
                "song_artists": "Sergio Mendes & Brasil '66"
            },
        ],
    }

Where the template utilizes loop.index:

{% for song in class_plan["playlist"] %}
   <input type="hidden" name="song_title_{{ loop.index }}" value="{{ song['track_title'] }}">
{% endfor %}   

I know that I can access the numbers with post[i][0][-1] and the strings with post[i][0][:-2], and I have worked out, then could do same for each required key, and finally zip it all up, then perhaps render as a tuple:

titles = [(key[:-2], val) for key, val in post if key[:-2] == 'song_title']
artists = [(key[:-2], val) for key, val in post if key[:-2] == 'song_artists']
songs = zip(titles, artists)
tuple(songs)

((('song_title', 'Águas De Março'), ('song_artists', 'Elis Regina, Antônio Carlos Jobim')), \
(('song_title', 'Mas, Que Nada!'), ('song_artists', 'Jorge Ben Jor')), \
(('song_title', 'Mais Que Nada'), ('song_artists', "Sergio Mendes & Brasil '66")))

Then do something to jsonify it (probably with Flasks jsonify), but I am sure there are much more eloquent (if not correct) and Pythonic approaches and hope you'll enlighten me.

Thanks.

CodePudding user response:

It would probably be easiest to loop over the numbers and build the dictionaries, something like this:

import itertools

songs = []
try:
    for idx in itertools.count(1):
        # access tuple as dict
        post_item = dict(post)
        songs.append({"song_title": post_item["song_title_%d" % idx],
            "song_artists": post_item["song_artists_%d" % idx]})
except LookupError: # or whatever exception signals that there aren't any more
    pass # just halt the loop, nothing more needed

If you prefer to put a hard limit on the number of songs you look up (in case something bizarre happens), you could iterate over range(1, 11) or range(1, 101) etc; and if your numbering starts from zero, omit the 1 from count() or range().

  •  Tags:  
  • Related