You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python批量分配预制播放列表问题:所有用户均匹配同一列表

用户预制播放列表分配结果集中问题的解决

问题背景

  • 数据结构:
    • users:键为user1到user100,每个值是含10首歌曲的字符串列表
    • premade_playlists:键为premade1到premade100,每个值是含约50首歌曲的字符串列表
  • 需求:为每个用户分配满足以下条件的预制播放列表:列表中至少有3首用户听过的歌曲,同时至少有3首用户未听过的歌曲
  • 问题:运行原代码后,所有用户都被分配了premade1,期望分配结果更分散
  • 歌曲来源:所有歌曲均通过random.sample()从包含600首歌的数据库随机选取

原代码

premade_for_user:dict[str, list[str]] = {}

for user in users:
    for premade in premade_playlists:
        listened_to = 0
        not_listened_to = 0
        while listened_to < 3 and not_listened_to < 3:
            for song in premade_playlists[premade]:
                if listened_to >= 3 and not_listened_to >= 3:
                    print("Didn't work?")
                elif song in users[user]:
                    listened_to += 1
                elif song not in users[user]:
                    not_listened_to += 1
                else:
                    print("stuck") 
        else:
            premade_for_user[user] = premade
            break

问题原因

原代码逻辑存在两处关键错误:

  1. 循环逻辑错误:while listened_to < 3 and not_listened_to < 3会反复遍历当前播放列表的歌曲,直到两个计数都≥3。一旦满足条件,直接进入while的else分支(循环正常结束无中断),随即给用户分配当前播放列表并跳出外层的播放列表循环。由于premade1大概率满足条件(50首歌与用户10首歌的交集很容易≥3,剩余非交集歌曲也≥3),所以所有用户都会优先分配到它。
  2. 效率低下:通过遍历每首歌统计计数,比直接计算集合交集的方式慢很多,尤其当歌曲数量较多时。

修正后的代码

import random

premade_for_user: dict[str, str] = {}

for user in users:
    user_song_set = set(users[user])  # 转换为集合,提升成员判断效率
    eligible_playlists = []
    
    # 筛选所有符合条件的预制播放列表
    for playlist_name, playlist_songs in premade_playlists.items():
        playlist_song_set = set(playlist_songs)
        common_songs_count = len(user_song_set & playlist_song_set)
        unheard_songs_count = len(playlist_song_set - user_song_set)
        
        if common_songs_count >= 3 and unheard_songs_count >= 3:
            eligible_playlists.append(playlist_name)
    
    # 从符合条件的列表中随机选择一个分配
    if eligible_playlists:
        premade_for_user[user] = random.choice(eligible_playlists)
    else:
        # 无符合条件时的 fallback 处理
        premade_for_user[user] = "no_eligible_playlist"

修正说明

  • 集合优化:将用户歌曲和播放列表歌曲转换为集合,利用集合运算快速计算交集(听过的歌)和差集(未听过的歌)的数量,大幅提升效率。
  • 随机分配:先收集所有符合条件的播放列表,再通过random.choice()随机选取一个,确保分配结果分散。
  • 类型修正:原代码中premade_for_user的注释类型与实际赋值不符,修正为dict[str, str](键为用户ID,值为播放列表ID)。
  • 异常处理:增加了无符合条件播放列表时的 fallback 逻辑,避免报错。

内容的提问来源于stack exchange,提问作者Enusa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:01:03