【问题标题】:How to convert a dictionary to query string in Python?如何在 Python 中将字典转换为查询字符串?
【发布时间】:2011-12-09 18:16:02
【问题描述】:

使用cgi.parse_qs()后,如何将结果(字典)转换回查询字符串?寻找类似于urllib.urlencode() 的东西。

【问题讨论】:

标签: python urllib2 urllib


【解决方案1】:

Python 3

urllib.parse.urlencode(query, doseq=False, [...])

映射对象或可能包含 str 或 bytes 对象的二元素元组序列转换为百分比编码的 ASCII 文本字符串。

——Python 3 urllib.parse docs

dict 是一个映射。

旧版 Python

urllib.urlencode(query[, doseq])
映射对象或二元素元组序列转换为“百分比编码”字符串...由'&'字符分隔的一系列key=value对...

——Python 2.7 urllib docs

【讨论】:

  • 这是真的,但cgi.parse_qs() 返回的dict 实际上有lists 作为它的“值”。直接传递这些将导致看起来很奇怪的查询字符串。
  • 确实如此。这将教会我阅读比第一句话更多的内容!
  • urllib.parse.urlencode 在 Python 3 中。
  • 问题是urlencode会把空格转成+,不推荐。
  • @user1633272:谁不推荐?
【解决方案2】:

在python3中,略有不同:

from urllib.parse import urlencode
urlencode({'pram1': 'foo', 'param2': 'bar'})

输出:'pram1=foo&param2=bar'

为了兼容python2和python3,试试这个:

try:
    #python2
    from urllib import urlencode
except ImportError:
    #python3
    from urllib.parse import urlencode

【讨论】:

    【解决方案3】:

    你正在寻找类似urllib.urlencode()的东西正是

    但是,当您调用 parse_qs()(与 parse_qsl() 不同)时,字典键是唯一的查询变量名称,而值是每个名称的 值列表

    为了将此信息传递给urllib.urlencode(),您必须“展平”这些列表。以下是使用元组列表理解的方法:

    query_pairs = [(k,v) for k,vlist in d.iteritems() for v in vlist]
    urllib.urlencode(query_pairs)
    

    【讨论】:

    • 或者你可以通过doseq=True
    • @downvoter:我该如何改进这个答案?我写它已经六年了!
    【解决方案4】:

    也许你正在寻找这样的东西:

    def dictToQuery(d):
      query = ''
      for key in d.keys():
        query += str(key) + '=' + str(d[key]) + "&"
      return query
    

    它需要一个字典并将其转换为查询字符串,就像 urlencode 一样。它会在查询字符串中附加一个最后的“&”,但如果有问题,return query[:-1] 会解决这个问题。

    【讨论】:

    • 你见过str.join() 吗? urllib.quote_plus() 怎么样?
    • @garbados 您的解决方案应该适用于简单的情况。但是,请查看 urllib.py 中的 urlencode(它应该在您的 Python 安装中),看看为什么创建查询字符串有时不像您的答案所暗示的那么简单(特别是需要“引用”某些字符在 URL 中无效)。 @Ignacio 还引用了两个函数,它们可以清理您的实现并使其正确。
    • 啊,确实。对不起,粗鲁的实施。这表明我应该更加小心地回答我从未遇到过的问题。
    • 虽然这可能不是最好的答案,但当我点击这个问题的标题时,这正是我想看到的。我在 dict 中只有 4 个项目,我需要将其转换为由“&”分隔的名称 = 值对。我的价值观受到控制。 str.join() 在我的情况下很方便,但我不需要 quote_plus(),因为它不是面向公众的代码 :) 谢谢!
    • @harperville 但更正确的方法 (from urllib.parse import urlencode; urlencode(your_dict)) 比这更短更容易!我承认,重新发明轮子有时是明智的,即使是粗制滥造的,当使用现有的、设计良好的轮子很昂贵或不方便时,但在这里使用现成的轮子比滚动你自己的劣质轮子更容易、更快捷.
    猜你喜欢
    • 2023-01-04
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2012-06-14
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多