Python如何实现歌曲随机推荐不重复且全部展示后提示无更多内容
歌曲推荐小程序去重推荐实现方案
核心实现思路
- 重构原分散的音乐数据为嵌套字典结构,省去大量重复的分支判断代码,后续新增流派/乐队/歌曲时直接修改字典即可
- 用户选定乐队后,单独复制一份该乐队的歌曲列表作为待推荐池,提前打乱顺序
- 每次推荐直接从待推荐池取出一首(取出后自动从池中移除),天然避免重复推荐
- 每次请求新推荐前先检查待推荐池长度,为空时直接提示无更多可推荐内容
完整可运行代码
import random # 统一存储流派-乐队-歌曲的嵌套字典 music_lib = { "Power metal": { "Helloween": ["Pumpkins united", "Halloween"], "Dragonforce": ["Heroes of our time", "Fury of the storm"], "Hammerfall": ["Hearts on fire", "Riders of the storm"] }, "Melodic death metal": { "Kalmah": ["Hades", "Seventh Swamphony"], "Insomnium": ["While we sleep", "Down with the sun"], "Ensiferum": ["Victory song", "Rum, woman, victory", "Lai la hei"], "Wintersun": ["Winter Madness", "Sons of winter and stars"] }, "Progressive metal": { "Dream theater": ["As I am", "The enemy inside"], "Symphony X": ["Sea of lies", "Inferno"] }, "Rock": { "Bon Jovi": ["It's my life", "Wanted dead or alive"], "Nirvana": ["Smells like teen spirit", "Come as you are"] } } # 选择流派逻辑 all_genres = list(music_lib.keys()) selected_genre = input(f"\nSelect a music genre from available: {all_genres}:") while selected_genre not in all_genres: selected_genre = input(f"\nYou entered the wrong name. Please, enter again: {all_genres}:") # 选择乐队逻辑 band_list = list(music_lib[selected_genre].keys()) selected_band = input(f"\nReffering to chosen genre, I have bands such as: {band_list}. Choose a specific band and I'll suggest a random song:\n") while selected_band not in band_list: selected_band = input(f"\nYou entered the wrong name. Please, enter again from available here {band_list} and I'll suggest random song:\n") # 初始化待推荐歌曲池:复制对应乐队的歌单后打乱顺序 remaining_songs = music_lib[selected_genre][selected_band].copy() random.shuffle(remaining_songs) # 推荐歌曲逻辑 def recommend_song(): if not remaining_songs: print("当前乐队已无更多可推荐内容") return False song = remaining_songs.pop() print(f"Suggested song: {song}") return True # 首次推荐 recommend_song() # 后续推荐循环 while True: next_opt = input("\nWould you like me to suggest one more song from the band of your choice ? Answer yes or no:\n") if next_opt == "no": print("Enjoy your music") break elif next_opt == "yes": has_song = recommend_song() # 无剩余歌曲时直接结束循环 if not has_song: break
关键修改说明
- 数据结构重构后,删除了原代码中数十行重复的if判断逻辑,代码可读性和可维护性大幅提升
- 使用
copy()方法复制歌曲列表,避免修改原字典中存储的基础数据 shuffle()+pop()的组合实现比random.choice()+remove()的方案效率更高,也不会出现重复歌曲导致的删除错误问题- 新增待推荐池为空的判断逻辑,符合需求中全部歌曲推荐完后提示的要求
内容的提问来源于stack exchange,提问作者Tomek
相关产品推荐
相关产品推荐

