在Python中,从文本文件中选择不重复的随机行
我有一个程序,打印歌曲的第一个字母和他们的艺术家,你必须猜这首歌 我希望歌曲被随机选择,但只显示一次,我希望游戏结束后,列表中的所有歌曲都已显示 下面是我的文本文件“songs.txt”的一个示例: Billie Eilish-派对结束时在Python中,从文本文件中选择不重复的随机行,python,loops,file,random,repeat,Python,Loops,File,Random,Repeat,我有一个程序,打印歌曲的第一个字母和他们的艺术家,你必须猜这首歌 我希望歌曲被随机选择,但只显示一次,我希望游戏结束后,列表中的所有歌曲都已显示 下面是我的文本文件“songs.txt”的一个示例: Billie Eilish-派对结束时 阿里安娜·格兰德-男朋友 TMC-无Scrubs 命运之子-说出我的名字 阿黛勒-你好 凯蒂·佩里-加利福尼亚女孩 BTS-家庭 以下是我的输出: 歌曲的第一个字母是:H,歌手是:BTS 这是我的密码: import random def rand
阿里安娜·格兰德-男朋友
TMC-无Scrubs
命运之子-说出我的名字
阿黛勒-你好
凯蒂·佩里-加利福尼亚女孩
BTS-家庭 以下是我的输出:
歌曲的第一个字母是:H,歌手是:BTS
这是我的密码:
import random
def random_line(songs):
lines = open(songs).read().splitlines()
return random.choice(lines)
random =(random_line('songs.txt'))
artist = (random.split(' - ')[0])
song = (random.split(' - ',1)[1])
song_letter = song[0]
print ("The first letter of the song is: " + song_letter + " and the artist is: " + artist)
将
random.choice(行)
存储在变量中,然后将其从行列表中删除
def random_line(songs):
lines = open(songs).read().splitlines()
random_line = random.choice(lines)
lines.remove(random_line)
return random_line
我假设您将在某种while或for循环中运行它,并且可能需要根据实际存储的输入评估用户输入。因此,您可能希望在函数中包含返回艺术家song_letter。你没有得到第一个字母,因为你没有索引到歌曲足够远
import random
"""I've used a list of the songs you provided but you may wish to import these from a txt file and then convert to a list"""
songs = ['Billie Eilish - When The Party Is Over',
'Ariana Grande - boyfriend',
'TMC - No Scrubs',
"Destiny's Child - Say My Name",
"Adele - Hello",
"Katy Perry - California Girls",
"BTS - Home"]
def artist_song(song):
artist = song.split(' - ')[0]
song_letter = song.split(' - ')[1][0]
print ("The first letter of the song is: " + song_letter + " and the artist is: " + artist)
"""You may chose to use return (artist,song_letter) insteas so you can use them for comparision"""
song = random.choice(songs)
artist, song_letter = artist_song(song)
songs.remove(song)
您可能希望多次执行此操作,直到没有孤独者的任何歌曲,并且您可以按如下方式执行此操作:
while songs:
song = random.choice(songs)
artist, song_letter = artist_song(song)
x = input('User input here: ').lower()
if x == song.split(' - ')[1].lower():
"""What to do if their input matches"""
pass
else:
"""What to do if the song is wrong"""
pass
songs.remove(song)
使用输入,考虑其他因素,如输入验证,因此确保用户输入仅是字母,没有数字/空格等。您可以包括一个计数器来跟踪得分。
< P>这里是一个解决方案,以一个生成器的形式,基于改组并用<代码>收益< /代码>实现。对于一个包含n个项目的列表,洗牌需要O(n)个时间,在迭代过程中摊销,以产生每首歌曲的固定时间。与“从列表中删除”解决方案相比,它的一个优点是生成器可以运行多次,如下面的代码所示。它将遍历整个序列,但如果您继续请求更多歌曲,则会产生不同的顺序随机导入
歌曲列表=[
“Billie Eilish-派对结束时”,
“Ariana Grande-男朋友”,
“TMC-无Scrubs”,
“命运之子-说出我的名字”,
“阿黛尔-你好”,
“凯蒂·佩里-加利福尼亚女孩”,
“BTS-家庭”
]
def song_info():
随机播放(歌曲列表)
对于范围内的i(len(song_列表)):
产量列表[i]。拆分('-'))
def播放列表():
对于宋_info()中的(艺术家、标题):
打印(“歌曲的第一个字母是:“+title[0]+”,艺术家是:“+artist”)
播放列表()
打印(“太有趣了,我们再来一次吧!”)
播放列表()
显然,如果您预期歌曲的“数据库”不断增长,您可以通过读取文件而不是将其硬连接到代码中来填充歌曲列表
将数据存储为artist&title的列表/元组,而不是要拆分的字符串,可能更有意义。这会将song\u列表
和song\u info()
生成器更改为:
歌曲列表=[
(“Billie Eilish”,“派对结束时”),
(“Ariana Grande”,“男朋友”),
(“TMC”,“无Scrubs”),
(“命运之子”,“说出我的名字”),
(“阿黛尔”,“你好”),
(“凯蒂·佩里”、“加利福尼亚女孩”),
(“BTS”、“家庭”)
]
def song_info():
随机播放(歌曲列表)
对于范围内的i(len(song_列表)):
产量表[i]
在我看来,哪一个更干净。为什么不只是列表和循环通过洗牌版本呢?我不知道这一点,我会调查一下,谢谢!