【问题标题】:Why a generator object is obtained instead of a list为什么获取生成器对象而不是列表
【发布时间】:2015-04-30 00:30:37
【问题描述】:

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

我想将“标准”格式的项目的所有 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

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

【问题讨论】:

  • 列表解析的语法涉及[...]。也可以直接urls = [...]

标签: python list list-comprehension


【解决方案1】:

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

【讨论】:

  • 我尝试了urls2.append([md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard"]) 并得到了这个结果:[['http://fake1001/Standard', 'http://fake1002/Standard']] 因此,我将其稍微更改为:urls2 = [md["url"] for m in mylist for md in m["mdata"] if md["fmt"] == "Standard"],它会根据需要提供['http://fake1001/Standard', 'http://fake1002/Standard']
猜你喜欢
  • 2020-02-03
  • 2018-09-15
  • 2021-09-22
  • 2016-09-24
  • 1970-01-01
  • 2018-03-20
  • 2012-09-10
  • 2013-03-12
  • 1970-01-01
相关资源
最近更新 更多