【问题标题】:Mixing List and Dict in PythonPython中的混合列表和字典
【发布时间】:2014-01-20 04:46:27
【问题描述】:

我想知道如何在 Python 上将 list 和 dict 混合在一起?我知道在 PHP 上,我可以这样做:

$options = array(
    "option1", 
    "option2", 
    "option3" => array("meta1", "meta2", "meta3"), 
    "option4" 
);

问题是 python 对不同的列表有不同的括号。 () 表示元组,[] 表示列表,{} 表示字典。似乎没有任何方法可以混合它们,而且我不断收到语法错误。

我现在使用 python 2.7。请指教如何正确操作。

非常感谢,

鲁法斯

更新 1:

我会稍微详细说明我正在尝试做的事情。我正在尝试编写一个简单的 python 脚本来执行一些 API 请求:

http://www.diffbot.com/products/automatic/article/

相关部分是字段查询参数。它类似于 ...&fields=meta,querystring,images(url,caption)... 。所以上面的数组可以写成(在PHP中)

$fields = array(
    'meta',
    'querystring',
    'images' => array('url', 'caption')
);

并且 $fields 将被传递给一个方法进行处理。将返回结果,如下所示:

$json = diffbot->get("article", $url, $fields);

问题是 - 我用 PHP 编写它没有问题,但是当我尝试用 Python 编写它时,事情并不像看起来那么容易......

【问题讨论】:

  • 这样的? x = ['first', 'second', {'third':['blah']}]
  • 是这样的: x = ['first', 'second', 'third':['blah','blah'], 'forth'] 。一直试图在这里和那里用 {} 替换括号以使代码工作,但它没有。

标签: python list python-2.7 dictionary


【解决方案1】:

你可以这样做:

options = {
    "option1": None, 
    "option2": None,
    "option3": ["meta1", "meta2", "meta3"], 
    "option4": None,
}

options 在这种情况下是字典。 如果您需要字典中的顺序,可以使用 OrderedDict。

如何使用OrderedDict

from collections import OrderedDict

options = OrderedDict([
    ("option1", None),
    ("option2", None),
    ("option3", ["meta1", "meta2", "meta3"]), 
    ("option4", None),
])

print options["option3"]
print options.items()[2][1]
print options.items()[3][1]

输出:

['meta1', 'meta2', 'meta3']
['meta1', 'meta2', 'meta3']
None

在这里,您可以使用键(如option3)或索引(如23)访问options

免责声明。 我必须强调,这个解决方案不是 PHP 和 Python 之间的一对一映射。 PHP 是另一种语言,具有其他数据结构/其他语义等。您不能在 Python 和 PHP 的数据结构之间进行一对一的映射。还请考虑 Hyperboreus 的答案(我给了他+1)。它展示了另一种在 Python 中混合列表和字典的方法。另请阅读我们下面的讨论。

更新1。

你如何处理这样的结构?

您必须检查每种情况下的值具有哪种类型。 如果是列表(type(v) == type([]))可以加入; 否则你可以照原样使用它。

在这里,我将结构转换为类似 URL 的字符串:

options = {
    "option1": None,
    "option2": None,
    "option3": ["meta1", "meta2", "meta3"], 
    "option4": "str1",
}

res = []
for (k,v) in options.items():
    if v is None:
        continue
    if type(v) == type([]):
        res.append("%s=%s" % (k,"+".join(v)))
    else:
        res.append("%s=%s" % (k,v))

print "&".join(res)

输出:

option4=str1&option3=meta1+meta2+meta3

【讨论】:

  • @Hyperboreus:请看我关于OrderedDict的注释
  • 也可以使用空列表[] 而不是None 来表示没有元素。然后所有值都具有相同的类型,并且可以传递给相同的函数。 (有点)。
  • @IgorChubin 您仍然在混淆键和值。 PHP 数组是有序映射。根据文档,当数组声明的元素省略 => 时,它将被视为一个值,其键是下一个未使用的整数。所以我看不出你的答案与这个问题有什么关系。
  • @IgorChubin 感谢您提供负面证据。 options.items()[2][1]['meta1', 'meta2', 'meta3']。在 php 中 $options[2][1] 给出 "p"
  • @Hyperboreus:问题是“如何在 Python 上将 list 和 dict 混合在一起?”我并没有说它和 PHP 中的完全一样。
【解决方案2】:

这似乎做同样的事情:

options = {0: 'option1',
    1: 'option2',
    2: 'option4'
    'option3': ['meta1', 'meta2', 'meta3'] }

更笼统地说:

[] 表示列表,即有序集合:[1, 2, 3][x ** 2 for x in [1, 2, 3]]

{} 表示集合,即唯一(可散列)元素的无序集合和字典,即唯一(可散列)键和值之间的映射:{1, 2, 3}{'a': 1, 'b': 2}{x: x ** 2 for x in [1, 2, 3]}

() 表示(除其他外)元组,即不可变的有序集合:(1, 2, 3)

() 也表示生成器:(x ** 2 for x in (1, 2, 3))

你可以随意混合它们(只要集合的元素和字典的键是可散列的):

>>> a = {(1,2): [2,2], 2: {1: 2}}
>>> a
{(1, 2): [2, 2], 2: {1: 2}}
>>> a[1,2]
[2, 2]
>>> a[1,2][0]
2
>>> a[2]
{1: 2}
>>> a[2][1]
2

【讨论】:

  • 在这种情况下options[0]=='option1'options[1]=='option2'options[2]=='option4',但options[3]==KeyError: 3
  • @adsmith 同样在 PHP 中 $options 不包含密钥 3。只有那个 php 以不同的方式处理未知键。
  • @Hyperboreus 但他不是用 PHP 编程,所以我看不出这有什么关系。 OPs 示例似乎是如何将列表放入列表中,这显然不是如何做到的。 options = ['option1','option2',['meta1','meta2','meta3'],'option4'] 是一个更干净的数据结构。不要仅仅因为 PHP 就是这样做的——让它变得更好。
【解决方案3】:

我很确定我的问题有 3 个答案,虽然它获得了 -1 票,但它最接近我想要的答案。现在很奇怪,当我想把它选为“已接受的答案”时它已经消失了:(

回顾一下,删除的答案建议我应该这样做:

options = [
    "option1", 
    "option2", 
    {"option3":["meta1", "meta2", "meta3"]}, 
    "option4" 
]

这非常适合我处理列表中每个项目的方式。我只是遍历所有值并检查其类型。如果它是一个字符串,像往常一样处理它。但是当是dict/list时,处理方式就不一样了。

最终,我设法让它工作,我得到了我想要的。

特别感谢 Igor Chubin 和 Hyperboreus 为我提供建议和想法,让我测试并发现我一直在寻找的答案。非常感谢。

谢谢!

鲁法斯

【讨论】:

    猜你喜欢
    • 2021-04-09
    • 2014-08-03
    • 2021-10-06
    • 1970-01-01
    • 2022-01-19
    • 2012-08-11
    • 2012-07-17
    • 2013-02-19
    • 1970-01-01
    相关资源
    最近更新 更多