views:

81

answers:

3

How can I get a URL-encoded version of a multidimensional dictionary in Python? Unfortunately, urllib.urlencode() only works in a single dimension. I would need a version capable of recursively encoding the dictionary.

For example, if I have the following dictionary:

{'a': 'b', 'c': {'d': 'e'}}

I want to obtain the following string:

a=b&c[d]=e
+1  A: 

Something like this?

a = {'a': 'b', 'c': {'d': 'e'}}

url = urllib.urlencode([('%s[%s]'%(k,v.keys()[0]), v.values()[0] ) if type(v)==dict else (k,v) for k,v in a.iteritems()])

url = 'a=b&c%5Bd%5D=e'
eumiro
pablobm
Then you will have to iterate over the dictionary like I did and urlencode each item separately...
eumiro
A: 

what about json.dumps and json.loads?

d = {'a': 'b', 'c': {'d': 'e'}}
s = json.dumps(d)  # s: '{"a": "b", "c": {"d": "e"}}'
json.loads(s)  # -> d
sunqiang
No. What I want is to URL-encode. No more, no less
pablobm
+1  A: 

OK guys. I implemented it myself:

import urllib

def recursive_urlencode(d):
    def recursion(d, base=None):
        pairs = []

        for key, value in d.items():
            if hasattr(value, 'values'):
                pairs += recursion(value, key)
            else:
                new_pair = None
                if base:
                    new_pair = "%s[%s]=%s" % (base, urllib.quote(unicode(key)), urllib.quote(unicode(value)))
                else:
                    new_pair = "%s=%s" % (urllib.quote(unicode(key)), urllib.quote(unicode(value)))
                pairs.append(new_pair)
        return pairs

    return '&'.join(recursion(d))

Still, I'd be interested to know if there's a better way to do this. I can't believe Python's standard library doesn't implement this.

pablobm
Why should it? This is not in any way a standard format. The thing with the square brackets is a PHP-specific peculiarity not present in most other languages/frameworks or any web standard.
bobince
It may not be a pure-blood RFC-described IETF/W3C-backed holy-macaroni standard, but it's so commonly used nowadays that its not being included in Python's standard library does defy my comprehension.I have developed web applications in a number of platforms and languages, and this has always been the convention. And this includes Python-based environments such as Django: so no, it's not a PHP-only thing anymore.
pablobm