Python在大型列表中访问字典 - 非官方GoogleMusicAPI

0 投票
2 回答
662 浏览
提问于 2025-04-18 02:16

我刚开始学Python,还是个新手!不过,我会一直在学习的!

我有一个很大的字典列表。这些字典是通过一个非官方的谷歌音乐API生成的,具体来说,是下面链接中的.py文件。

https://github.com/simon-weber/Unofficial-Google-Music-API/blob/develop/gmusicapi/clients/mobileclient.py

我使用了一个叫 get_all_songs 的函数,它会生成这个列表。我已经成功地把数据输出到一个文本文件里。这个函数说它会创建一个包含很多字典的大列表。

我尝试了这里所有我能找到的相关方法,但还是没弄明白怎么访问里面的字典。每首歌都是一个字典。我想做的事情有:

  1. 从每个字典中删除那些值为空的键值对。例如,下面加粗的第一个键'comment'没有值,所以我想把它删掉。

  2. 从每个字典中提取特定键的信息。例如,获取每首歌(每个字典)的艺术家值和播放次数值,然后可以对这些数据进行操作。比如,把某个艺术家的所有歌曲的播放次数加起来。http://newcoder.io/Part-2-Graph/

这是我从函数生成的文本文件中提取的一个字典。此外,我不知道为什么每个键和值前面都有(u')或(u")。我觉得这只是通过API捕获的信息的一部分。我有一种感觉,这些U可能会影响字典的结构,但我可能完全错了。

{
    u'comment': u'', 
    u'rating': u'0', 
    u'artistId': [u'Amicfexiiup7erm7exmzdyimive'], 
    u'composer': u'', 
    u'year': 0, 
    u'creationTimestamp': u'1395972652473326', 
    u'id': u'e6c27479-1d7d-37a6-a788-52bcb8477e42', 
    u'album': u'', 
    u'totalDiscCount': 0, 
    u'title': u"Chromeo - Jealous (I Ain't With It) (The Chainsmokers Remix).mp3",
    u'recentTimestamp': u'1395972654776000', 
    u'albumArtist': u'', 
    u'trackNumber': 0, 
    u'discNumber': 0, 
    u'deleted': False, 
    u'storeId': u'Tshltra3tgk3q6ktjdxgxjtljky', 
    u'nid': u'Tshltra3tgk3q6ktjdxgxjtljky', 
    u'totalTrackCount': 0, 
    u'estimatedSize': u'3662316', 
    u'albumId': u'B4fo7oogd5ka2jfhlddjwazivlm', 
    u'beatsPerMinute': 0, 
    u'genre': u'', 
    u'playCount': 21, 
    u'artistArtRef': [{u'url': u'REMOVED LINK BECAUSE STACKOVERFLOW LIMIT'}], 
    u'kind': u'sj#track', 
    u'artist': u'Chromeo', 
    u'lastModifiedTimestamp': 
    u'1396305526006069', 
    u'clientId': u'9gG999dOb6DKkkGTcw/9GQ', 
    u'durationMillis': u'229000'
} 

每个字典基本上都有相同的键,所以它们在列表中并不是唯一的。

抱歉说得有点长!无论如何,感谢你的时间!

2 个回答

0

1. 从字典中删除那些值为空的键值对

要做到这一点,你可以选择直接在当前的字典上进行修改(删除),或者创建一个新的字典,只包含你感兴趣的键值对。

如果你要修改当前的字典,假设它叫做 song_info

songs = client.get_all_songs()
for song in songs:   
    for key, value in song.items():
        if value == u'':
            del song[key]

如果你想创建一个新的字典,只包含你感兴趣的键值对,可以这样做:

songs = client.get_all_songs()
songs_without_empty_values = []
for song in songs:
    new_song_info = {key : song[key]
                     for key in song.items()
                     if song[key] != u''}
    songs_without_empty_values.append(new_song_info)

你可以根据自己对“没有值”的定义来调整 if 语句;我假设任何值是 u''(也就是空字符串)都算是没有值。

2. 从每个字典中获取特定键的信息

我对这里的具体要求还有点不确定。

假设你想遍历所有的字典,获取所有播放次数的列表,那么可以这样做:

songs = client.get_all_songs()
key = u'playCount'
values = [song[key] for song in songs]

请注意,上面的代码非常简单,如果 key 不在某个字典中,会引发 KeyError 错误,这一点没有考虑到。

1

当你调用 get_all_songs 时,它会返回一个字典的列表。你可以这样逐个查看这个列表:

songs = client.get_all_songs()
for song in songs:
    ...

每次循环时,它会从列表中取出一个字典,并把它赋值给 song

如果你想从字典中去掉那些空的键,可以创建一个新的字典,只保留那些有值的键值对:

clear_song = {k:v for (k,v) in song.iteritems() if v}

这就是字典推导式,基本上等同于:

clear_song = dict()
for key, value in song.iteritems():
    if value:
        clear_song[key] = value

它会去掉任何值为假(non-Truthy)的项目,比如 0u''。如果你只想去掉空字符串,那就需要做一个更明确的测试:

clear_song = {k:v for (k,v) in song.iteritems() if v.strip() != u''}

要遍历所有歌曲并生成清晰的歌曲列表,你可以把这个加到上面的循环中,或者你也可以在一个单独的列表推导式中完成:

clear_songs = [
    {k:v for (k,v) in song.iteritems() if v}
    for song in songs
]

要访问特定的字典,你需要知道它在列表中的位置:

clear_songs[77]['title'] # get the title of the 78th song in the list

或者你可以使用 filter 来找到匹配的字典:

filter(lambda x: x['title'] == "Chromeo - Jealous (I Ain't With It) (The Chainsmokers Remix).mp3", clear_songs)['estimatedSize'] # return '3662316'

你可以把这个放进一个方便的函数里:

def find_song(key, value, songs):
    return filter(lambda x: x[key] == value, songs)

然后通过以下方式调用它:

find_song('title', 'Chromeo - Jealous ...', clear_songs) # will return the matching dict

撰写回答