如何实现按字符串中的数值降序排列列表元素并应用于Discord LastFM机器人命令
Got it, let's fix this sorting issue for your LastFM Discord command! Here's how you can sort that list of user-playcount strings in descending order based on the numeric value:
Step 1: Add a Helper Function to Extract Playcounts
We need a way to pull the numeric playcount from each string in your wk list. We'll use a regular expression to find the number in each entry, then convert it to an integer to use as our sorting key.
Step 2: Sort the List Using the Helper Function
Use Python's built-in sorted() function, passing our helper as the key parameter and setting reverse=True to get descending order.
Modified Code
Here's your updated lastfm_whoknows function with the sorting logic added:
import re # Make sure to import this at the top of your file @lastfm.command(name="whoknows",aliases=['wk'],help="Who plays the artist most in a guild") async def lastfm_whoknows(self,ctx:Context,*,artist:str=None): wk = [] db = self.db["lastfm"]["lastfm"] to_find = {"m_id":ctx.author.id} found = db.find(to_find) for z in found: async with aiohttp.ClientSession() as session: params= {"api_key" : "ok", "user" : z["username"], "period" : "overall", "limit" : 1, "method":"user.getRecentTracks", "format":"json"} async with session.get(url="http://ws.audioscrobbler.com/2.0", params=params) as response: resp = await response.read() jsonData1 = json.loads(resp) for xy in ctx.guild.members: db = self.db["lastfm"]["lastfm"] to_find = {"m_id":xy.id} found = db.find(to_find) for x in found: async with aiohttp.ClientSession() as session: params= {"api_key" : "ok", "user" : x["username"], "artist" : jsonData1["recenttracks"]["track"][0]['artist']['#text'], "method":"artist.getInfo", "format":"json"} async with session.get(url="http://ws.audioscrobbler.com/2.0", params=params) as response: resp = await response.read() jsonData = json.loads(resp) alr = f'**{xy.name}** | **{jsonData["artist"]["stats"]["userplaycount"]}**' wk.append(alr) # --- New Sorting Logic Starts Here --- def get_playcount(entry): # Split the string at the |, take the right part, then extract digits playcount_part = entry.split('|')[-1] match = re.search(r'\d+', playcount_part) return int(match.group()) if match else 0 # Sort the list in descending order of playcount sorted_wk = sorted(wk, key=get_playcount, reverse=True) # --- New Sorting Logic Ends Here --- join = "\n".join(sorted_wk) em = discord.Embed(description=join,color=0xec1c24) await ctx.reply(embed=em, mention_author=False)
Quick Explanation
- The
get_playcountfunction splits each entry at the|character, grabs the part with the playcount, then uses regex to find the numeric value. sorted(wk, key=get_playcount, reverse=True)rearranges your list so entries with higher playcounts come first.- We fall back to 0 if no number is found (just in case of API errors or malformed data).
Small Optimization Note
You might want to move the aiohttp.ClientSession creation outside the nested loops—creating a new session for every member is inefficient. You could create one session at the start of the function and reuse it for all API calls!
内容的提问来源于stack exchange,提问作者Rohan

