为什么获取生成器对象而不是列表

时间:2015-04-30 00:30:38

标签: python list list-comprehension

使用Python 3.4,我有以下JSON

mylist = [
        {
          "mdata": [
                    {
                      "url" : "http://fake1001/Standard",
                      "fmt" : "Standard"
                    },                            
                    {
                      "url" : "http://fake1001/Thumb",
                      "fmt" : "Thumb"
                    }                                      
                    ]
        },
        {
          "mdata": [
                    {
                      "url" : "http://fake1002/Standard",
                      "fmt" : "Standard"
                    },                            
                    {
                      "url" : "http://fake1002/Large",
                      "fmt" : "Large"
                    }                                      
                    ]
        },
        {
          "mdata": [
                    {
                      "url" : "http://fake1003/Thumb",
                      "fmt" : "Thumb"
                    },                            
                    {
                      "url" : "http://fake1003/Large",
                      "fmt" : "Large"
                    }                                      
                    ]
        }          
      ]

我想将所有带有“标准”格式的商品网址放入列表中:

urls = []

for m in mylist:
  for md in m["mdata"]:
    if md["fmt"] == "Standard":
      urls.append(md["url"])

print(urls)

我得到以下结果:

['http://fake1001/Standard', 'http://fake1002/Standard']

现在,我尝试使用列表推导来完成相同的任务:

urls2 = []
urls2.append(md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard")

print(urls2)

但是,我得到了一个生成器对象:

[<generator object <genexpr> at 0x000000000860F510>]

要获取网址,我可以在生成器对象上调用next():

print(next(urls2[0]))
print(next(urls2[0]))

这给了我这个:

http://fake1001/Standard
http://fake1002/Standard

我想知道的是为什么列表推导给出了一个生成器对象,以及是否有任何方法可以避免这种情况?

1 个答案:

答案 0 :(得分:5)

generator expression的语法是:

(i for i in range(10))

您可以选择关闭带有迭代的函数的大括号:

sum(i for i in range(10))

你可能习惯了更常见的list comprehension

[i for i in range(10)]

要从生成器获取列表,只需使用list()将其清空。在你的情况下:

urls2.append(list(md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard"))

或者改为使用列表理解:

urls2.append([md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard"])