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.
4 Answers 4
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())
-
1\$\begingroup\$ Close but no cigar. I don't want quotes around 9999 for
MASTER_PORT
in the final result. \$\endgroup\$Bon Ami– Bon Ami2012年01月19日 08:53:40 +00:00Commented Jan 19, 2012 at 8:53 -
1\$\begingroup\$ @BonAmi You're right. I replaced the second
%s
with%r
to achieve that \$\endgroup\$Dor Shemer– Dor Shemer2012年01月19日 08:57:21 +00:00Commented Jan 19, 2012 at 8:57 -
\$\begingroup\$ Instead of the
(key,val)
you could simply writeitem
. 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. \$\endgroup\$Elmer– Elmer2012年01月19日 09:31:08 +00:00Commented Jan 19, 2012 at 9:31 -
\$\begingroup\$ @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. \$\endgroup\$dorsh– dorsh2012年01月19日 09:34:00 +00:00Commented Jan 19, 2012 at 9:34 -
\$\begingroup\$ 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. \$\endgroup\$IceArdor– IceArdor2015年09月18日 06:35:11 +00:00Commented Sep 18, 2015 at 6:35
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
-
\$\begingroup\$ You're right. I keep thinking with python 2.6 \$\endgroup\$Dor Shemer– Dor Shemer2012年01月19日 09:00:34 +00:00Commented Jan 19, 2012 at 9:00
-
2\$\begingroup\$ new syntax 3.6:
f"this is a string {variable}"
\$\endgroup\$JinSnow– JinSnow2017年02月05日 20:18:57 +00:00Commented Feb 5, 2017 at 20:18
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())
-
1\$\begingroup\$ Nice! Do you think you can improve the efficiency a little? \$\endgroup\$Chocolate– Chocolate2021年02月18日 00:38:52 +00:00Commented Feb 18, 2021 at 0:38
isinstance(False, int)
returnsTrue
, so instead offlag='False'
, you'd getflag=0
(both of which are not optimal). \$\endgroup\$