Flattening a dictionary into a string

  • Given:



    k = {'MASTER_HOST': '10.178.226.196', 'MASTER_PORT': 9999}


    I want to flatten into the string:



    "MASTER_HOST='10.178.226.196', MASTER_PORT=9999"


    This is the ugly way that I'm achieving this right now:



    result = []
    for i,j in k.iteritems():
    if isinstance(j, int):
    result.append('%s=%d' % (i,j))
    else:
    result.append("%s='%s'" % (i,j))

    ', '.join(result)


    I'm sure my developer colleagues are going to chastize me for this code. Surely there is a better way.


    I don't think it's that bad, unless perhaps you also have Boolean values in your dict, because `isinstance(False, int)` returns `True`, so instead of `flag='False'`, you'd get `flag=0` (both of which are not optimal).

  • For python 3.0+ (as @Serdalis suggested)



    ', '.join("{!s}={!r}".format(key,val) for (key,val) in k.items())


    Older versions:



    ', '.join("%s=%r" % (key,val) for (key,val) in k.iteritems())

    Close but no cigar. I don't want quotes around 9999 for `MASTER_PORT` in the final result.

    @BonAmi You're right. I replaced the second `%s` with `%r` to achieve that

    Instead of the `(key,val)` you could simply write `item`. iteritems returns tuples, and if you have multiple replacements in a string, you replace those using a tuple. You drop a second temporary variable and imo, you gain some readability.

    @Elmer That's interesting you say that, because I think novice pythoners might get more readability by using `(key,val)`, since it explains better what happens. But I guess that's a matter of taste. I do agree your way is more efficient.

    I know it's a dictionary and .iteritems returns `(key, val)`, so unless you have better variable names that warrant creating temporary variables, like `(food_name, price)`, you can save yourself the characters. It's all about increasing your signal to noise, and `(k,v)` or `(key, value)` is mostly noise.

  • Dor Shemer's method is very good, however since 3.0+ came out, pythoneque? language is moving towards:



    ', '.join("{!s}={!r}".format(k,v) for (k,v) in k.items())


    using .format instead of % () to format a string.



    both will give the same result and are correct.



    I used items for python 3.0+, but for python 2.x use iteritems


    You're right. I keep thinking with python 2.6

    new syntax 3.6: `f"this is a string {variable}"`

  • If you want exactly that output format, your way is quite OK imo. Because you want your keys unquoted and your values quoted if they're strings and unquoted if they're just numbers, there is no 'easy way' I think



    In general str(k) will return a string like {'MASTER_HOST': '10.178.226.196', 'MASTER_PORT': 9999}


  • For python 3.6+ you can use f-strings:


    ', '.join(f'{k}_{v}' for k, v in my_dict.items())

    Nice! Do you think you can improve the efficiency a little?

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used