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

jas*_*onC 0 python list-comprehension 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"
                    }                                      
                    ]
        }          
      ]
Run Code Online (Sandbox Code Playgroud)

我想将所有带有"标准"格式的项目的URL放入列表中:

urls = []

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

print(urls)
Run Code Online (Sandbox Code Playgroud)

我得到以下结果:

['http://fake1001/Standard', 'http://fake1002/Standard']
Run Code Online (Sandbox Code Playgroud)

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

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

print(urls2)
Run Code Online (Sandbox Code Playgroud)

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

[<generator object <genexpr> at 0x000000000860F510>]
Run Code Online (Sandbox Code Playgroud)

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

print(next(urls2[0]))
print(next(urls2[0]))
Run Code Online (Sandbox Code Playgroud)

这给了我这个:

http://fake1001/Standard
http://fake1002/Standard
Run Code Online (Sandbox Code Playgroud)

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

agc*_*nti 5

生成器表达式的语法是:

(i for i in range(10))
Run Code Online (Sandbox Code Playgroud)

对于采用迭代的函数,您可以选择关闭大括号:

sum(i for i in range(10))
Run Code Online (Sandbox Code Playgroud)

您可能习惯于更常见的列表理解:

[i for i in range(10)]
Run Code Online (Sandbox Code Playgroud)

要从发电机获取列表​​,只需将其排除list().在你的情况下:

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

或者使用列表理解:

urls2.append([md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard"])
Run Code Online (Sandbox Code Playgroud)