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

Why a generator object is obtained instead of a list

使用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"
                    }                                      
                    ]
        }          
      ]

我想将 "Standard" 格式的项目的所有 url 放入列表中:

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>]

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

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

这给了我这个:

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

我想知道的是为什么列表推导给出了一个生成器对象,有什么办法可以避免吗?

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"])