首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用python对多维字典进行urlencode

用python对多维字典进行urlencode
EN

Stack Overflow用户
提问于 2010-10-25 18:51:08
回答 8查看 8.9K关注 0票数 11

如何在Python中获得多维字典的URL编码版本?不幸的是,urllib.urlencode()只能在一个维度上工作。我需要一个能够递归编码字典的版本。

例如,如果我有以下字典:

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

我想要获取以下字符串:

a=b&c[d]=e
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-10-25 19:38:12

好了,各位。我自己实现的:

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()

不过,我还是很有兴趣知道是否有更好的方法来做这件事。我不敢相信Python的标准库没有实现这一点。

票数 11
EN

Stack Overflow用户

发布于 2010-10-25 18:59:57

像这样的东西?

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'
票数 3
EN

Stack Overflow用户

发布于 2016-08-22 22:22:28

基于@malaney的代码,我认为下面的代码很好地模拟了PHP函数http_build_query()

#!/usr/bin/env python3

import urllib.parse

def http_build_query(data):
    parents = list()
    pairs = dict()

    def renderKey(parents):
        depth, outStr = 0, ''
        for x in parents:
            s = "[%s]" if depth > 0 or isinstance(x, int) else "%s"
            outStr += s % str(x)
            depth += 1
        return outStr

    def r_urlencode(data):
        if isinstance(data, list) or isinstance(data, tuple):
            for i in range(len(data)):
                parents.append(i)
                r_urlencode(data[i])
                parents.pop()
        elif isinstance(data, dict):
            for key, value in data.items():
                parents.append(key)
                r_urlencode(value)
                parents.pop()
        else:
            pairs[renderKey(parents)] = str(data)

        return pairs
    return urllib.parse.urlencode(r_urlencode(data))

if __name__ == '__main__':
    payload = {
        'action': 'add',
        'controller': 'invoice',
        'code': 'debtor',
        'InvoiceLines': [
            {'PriceExcl': 150, 'Description': 'Setupfee'},
            {'PriceExcl':49.99, 'Description':'Subscription'}
        ],
        'date': '2016-08-01',
        'key': 'Yikes&ampersand'
    }
    print(http_build_query(payload))

    payload2 = [
        'item1',
        'item2'
    ]
    print(http_build_query(payload2))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4013838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档