[英]Select random lines from a text file without repeats in Python
我有一个程序可以打印歌曲的首字母和他们的艺术家,你必须猜出这首歌。
我希望随机选择歌曲,但只显示一次,并且我希望游戏在列表中的所有歌曲都显示后结束。
这是我的文本文件“songs.txt”的示例:
Billie Eilish - 当派对结束时
阿丽亚娜格兰德 - 男朋友
TMC - 无磨砂
命运之子 - 说出我的名字
阿黛尔——你好
凯蒂佩里 - 加州女孩
防弹少年团 - 主页
这是我的 output:
The first letter of the song is: H and the artist is: 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)
我假设您将在某种 while 或 for 循环中运行它,并且可能需要根据实际存储的输入评估用户输入。 因此,您可能希望在 function 中包含回归艺术家 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)
对于输入,请考虑其他因素,例如输入验证,因此请确保用户输入只有字母,没有数字/空格等。您可以包括一个计数器来跟踪分数。
将random.choice(lines)
存储在一个变量中,然后从行列表中删除它。
def random_line(songs):
lines = open(songs).read().splitlines()
random_line = random.choice(lines)
lines.remove(random_line)
return random_line
这是一个生成器形式的解决方案,基于改组并使用yield
实现。 洗牌需要 O(n) 时间来处理 n 个项目的列表,该时间在迭代中摊销以产生每首歌曲的恒定时间。 与从列表中删除解决方案相比,它的一个优点是生成器可以多次运行,如下面的代码所示。 它将遍历整个序列,但如果您继续请求更多歌曲,则会产生不同的顺序。
import random
song_list = [
"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 song_info():
random.shuffle(song_list)
for i in range(len(song_list)):
yield song_list[i].split(' - ')
def playlist():
for (artist, title) in song_info():
print ("The first letter of the song is: " + title[0] + " and the artist is: " + artist)
playlist()
print("That was so fun, let's do it again!")
playlist()
显然,如果您预计歌曲的“数据库”会增长,您可以通过从文件中读取而不是将其硬连接到代码中来填充song_list
。
将数据存储为艺术家和标题的列表/元组而不是作为要拆分的字符串也可能更有意义。 这会将song_list
和song_info()
生成器更改为:
song_list = [
("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 song_info():
random.shuffle(song_list)
for i in range(len(song_list)):
yield song_list[i]
我认为这更清洁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.