pythonurlencode

urlencode a multidimensional dictionary in python


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

Solution

  • OK people. I implemented it myself:

    import urllib
    
    def recursive_urlencode(d):
        """URL-encode a multidimensional dictionary.
    
        >>> data = {'a': 'b&c', 'd': {'e': {'f&g': 'h*i'}}, 'j': 'k'}
        >>> recursive_urlencode(data)
        u'a=b%26c&j=k&d[e][f%26g]=h%2Ai'
        """
        def recursion(d, base=[]):
            pairs = []
    
            for key, value in d.items():
                new_base = base + [key]
                if hasattr(value, 'values'):
                    pairs += recursion(value, new_base)
                else:
                    new_pair = None
                    if len(new_base) > 1:
                        first = urllib.quote(new_base.pop(0))
                        rest = map(lambda x: urllib.quote(x), new_base)
                        new_pair = "%s[%s]=%s" % (first, ']['.join(rest), 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))
    
    if __name__ == "__main__":
        import doctest
        doctest.testmod()
    

    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.