繁体   English   中英

Select 文本文件中的随机行,在 Python 中没有重复

[英]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_listsong_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM