如何从列表中选择随机但非近期的资产?

时间:2014-03-01 21:07:07

标签: python random flask queue deque

我有尝试从我的Flask应用程序中的数据库中提取“随机”项目的问题。此功能仅需要返回用户最近未观看的视频。我现在并不担心多个用户。我目前的做法不起作用。这就是我正在使用的:

@app.route('/_new_video')
def new_video():

以下是我要问的重要部分:

    current_id = request.args.get('current_id')
    video_id = random.choice(models.Video.query.all()) # return list of all video ids
    while True:
        if video_id != current_id:
            new_video = models.Video.query.get(video_id)

然后我把它归还:

            webm = new_video.get_webm() #returns filepath in a string
            mp4 = new_video.get_mp4() #returns filepath in a string 
            return jsonify(webm=webm,mp4=mp4,video_id=video_id)

随机范围从1开始,因为第一个资产已从数据库中删除,因此数字0与ID无关。理想情况下,用户不会收到他们最近观看过的视频。

1 个答案:

答案 0 :(得分:1)

我建议使用collections.deque存储最近观看的列表。它保存了一个像项目集合的列表,当你添加它时,如果它达到最大长度,它会自动删除最早的项目,先进先出。

import collections

这是一个可以用来获取最近没有观看过的随机视频的生成器。 denom参数将允许您更改最近观看的列表的长度,因为它用于确定您的recent_watched的最大长度,作为您的视频列表的一小部分。

def gen_random_vid(vids, denom=2):
    '''return  a random vid id that hasn't been recently watched'''
    recently_watched = collections.deque(maxlen=len(vids)//denom)
    while True:
        selection = random.choice(vids)
        if selection not in recently_watched:
             yield selection
             recently_watched.append(selection)

我将创建一个快速列表来演示它:

vids = ['vid_' + c for c in 'abcdefghijkl']

这是用法:

>>> recently_watched_generator = gen_random_vid(vids)
>>> next(recently_watched_generator)
'vid_e'
>>> next(recently_watched_generator)
'vid_f'
>>> for _ in range(10):
...     print(next(recently_watched_generator))
... 
vid_g
vid_d
vid_c
vid_f
vid_e
vid_g
vid_a
vid_f
vid_e
vid_c