循环遍历txt文件



我有一个txt文件,里面有艺术家、歌曲和流派的列表,格式如下:

song 1
genre 1 
artist 1
song 2
genre 2
artist 2
etc.

我得到了一个艺术家的名字,如果艺术家在文件中,我必须返回他们的歌曲名称。我写的代码是:

afile = open('music.txt')
header = afile.readline()
artists = afile.readlines()
afile.close()
for art in artists:
if art == artist:

我怎样才能得到歌曲的名字,它在歌手的名字上面两行?也有可能一个艺术家带着不同的歌曲出现几次。

首先,将文件读入列表。我假设你的文件格式是固定的:它包含

  • 指定歌曲名称的行
  • 指定类型
  • 的行
  • 指定artist
  • 的行
  • 空白行

注意,由于似乎没有标题,您不需要初始的header = afile.readline()

假设你将文件中的所有行读入一个名为lines

的列表中
lines = [line.strip() for line in afile] 
# You could also do 
# lines = afile.readlines()
# but that would leave behind trailing line breaks at the end of each line

现在,你知道

  • 从第一行开始,每隔四行为歌曲名。因此,将lines列表分割为每四行,从第一行开始,并将其保存为名为songs
  • 的列表
songs = lines[0::4]
  • 对其他信息做同样的事情:
genres = lines[1::4]
artists = lines[2::4]

现在,我们可以对这些列表进行zip(),以同时遍历它们,并打印与我们正在寻找的艺术家匹配的歌曲:

look_for_artist = "artist 2"
print(f"Songs by {look_for_artist}:")
for artist, genre, song in zip(artists, genres, songs):
if artist == look_for_artist:
print(song, genre)
# if you know that every artist has only one song, you can break the loop here since you found it already
# break   

如果你是为一群艺术家做这件事,我建议你先把数据读入字典(或collections.defaultdict)。然后,你可以查找给定艺术家的字典值,这将比遍历列表快得多。

考虑到一个艺术家可以有多首歌的情况,我们将使用一个字典,其中键是艺术家的名字,值是包含他们所有歌曲的列表。

import collections
lookup_dict = collections.defaultdict(list)
for artist, genre, song in zip(artists, genres, songs):
lookup_dict[artist].append((genre, song))

然后,你所需要做的就是:

for genre, song in lookup_dict[look_for_artist]:
print(song, genre)

您可以不需要将整个文件读入列表,然后将其处理为字典,方法是一行一行地以四行为一组读入文件,但我将把它留给您作为练习。

假设每个艺人只有一首歌曲(或者您正在搜索第一首匹配的歌曲),您可以这样解决:


def check_artist(chosen_artist):
afile = open('music.txt')
while afile:
song = afile.readline()
afile.readline() # Ignore the second line
artist = afile.readline()
if atrist == chosen_artist:
return song.split("n")
afile.readline() # Ignore the empty line
afile.close()
return "The artists do not have a song"

从第二个元素开始(因为这是第一个艺术家所在的位置),然后每隔第四个元素扫描一次艺术家。如果linelisti-th元素与artist匹配,则打印歌曲(在i-2处)。

for i in range(2, 100, 4):
if linelist[i] == artist:
print(linelist[i-2])

到目前为止所有的答案都是有效的,但它们确实依赖于格式总是4行的事实。如果有丢失的数据或有更多的数据,下面的代码也可以工作:

music = []
with open("music.txt") as f:
for line in f:
line = line.split()

# continue if line is empty
if not line:
continue
key = line.pop(0)
value = ' '.join(line)

# check for keys
if key=='song':
music.append({key: value})
if key=='genre':
music[-1].update({key: value})
if key=='artist':
music[-1].update({key: value})

这也是可扩展的,如果你的格式以后包含另一个键,如'album'.

如果你正在使用python3.10,你可以研究模式匹配来进一步简化代码。

相关内容

  • 没有找到相关文章

最新更新