2015-04-30 3 views
1

Использование 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 элементов с форматом «Стандарт» в списке:

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

Чтобы получить URLs, я могу назвать следующий() объекта генератора:

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

Что дает мне это :

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

Что я хочу знаете, почему понимание списка дает объект-генератор, и есть ли способ избежать этого?

+5

Синтаксис списка понимания включает '[...] '. Кроме того, вы можете напрямую выполнить 'urls = [...]' – thefourtheye

ответ

5

Синтаксис generator expression является:

(i for i in range(10)) 

При желании вы можете оставить скобки прочь для функций, которые принимают итерируемые:

sum(i for i in range(10)) 

Вы, наверное, привыкли к более общей list comprehension:

[i for i in range(10)] 

Чтобы получить список от генерато r просто exahust это с 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"]) 
+0

Получил! Спасибо за четкое объяснение! – jasonC

+0

@jasonC без проблем! – agconti

+0

Я пробовал 'urls2.append ([md [" url "] для m в моем списке для md в m [" mdata "], если md [" fmt "] ==" Standard "])' и получил это результат: '[[ 'HTTP: // fake1001/Стандарт', 'HTTP: // fake1002/Standard']]' Таким образом, я изменил его немного: 'urls2 = [мд [ "URL" ] для m в mylist для md в m ["mdata"], если md ["fmt"] == "Standard"] ' , который дает ' ['http: // fake1001/Standard', 'http:// fake1002/Standard '] ' по мере необходимости. – jasonC