List Comprehension返回空列表

时间:2016-11-17 17:54:13

标签: python mongodb python-2.7 pymongo list-comprehension

我试图查询MongoDB数据库并将两组结果(' _id'和#39; Team')分成两个单独的列表。

import pymongo

client = pymongo.MongoClient('localhost:27017')
db = client['db_name']

query = {'Team': {'$exists': 1}}
projection = {'_id': 1, 'Team': 1}

data = db['collection_name'].find(query, projection)  # line 9

id_list = [value for dict in data for key, value in dict.iteritems() if key == '_id']
teams_list = [value for dict in data for key, value in dict.iteritems() if key == 'Team']

print id_list
print teams_list

client.close()

对于上面的代码,' id_list'正如所料,但' teams_list'是空的。当我把'team_list'之前' id_list'我得到了预期的' teams_list'输出和' id_list'是空的。当我在两个列表推导之间重复数据调用(第9行)时,我得到两个列表的预期输出。

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

您需要将data定义为:

data = list(db['collection_name'].find(query, projection))

find()返回生成器时。一旦迭代了值,那些就会丢失。您需要将它们存储为list。这里list()执行该操作,即将生成器返回的项目存储为列表。

而不是迭代列表两次,更好的方法是两个单循环:

id_list, teams_list = [], []

#   v  `dict` is in-built data type, you should not be using it as variable
for d in data:
    for key, value in d.iteritems():
        if key == '_id':
            id_list.append(value)
        elif key == 'Team':
            teams_list.append(value)

有关生成器的更多信息,请参阅Generator wiki

答案 1 :(得分:0)

如前所述,罪魁祸首是find()方法,它返回一个>>> qs = (Track.objects ... .filter(listens__album=1294) ... .annotate(listen_count=models.Count('listens', distinct=True)) ... .order_by('-listen_count') ... ) 对象,当你第一次迭代时会消耗它。

但是你正在使用错误的方法来完成工作。您需要使用.aggregate()方法。

SELECT 
    "music_track"."id",
    "music_track"."name",
    COUNT(DISTINCT "music_listen"."id") AS "listen_count" 
FROM "music_track" 
INNER JOIN "music_listen" ON ("music_track"."id" = "music_listen"."track_id") 
 WHERE "music_listen"."album_id" = 1294 
GROUP BY "music_track"."id", "music_track"."name" 
ORDER BY "listen_count" DESC

Cursor方法与他的犯罪伙伴query = {'Team': {'$exists': 1}} cursor = db['collection_name'].aggregate([ {'$match': query } { '$group': { '_id': None, 'id_list': {'$push': '$_id'}, 'teams_list': {'$push': '$Team'} }} ]) 一样,在结果集上返回CommandCursor,这是一个像对象一样的生成器

因为我们按.aggregate()进行分组,所以迭代光标会生成一个文档,这意味着您可以放心地执行:

.find()

None