简体   繁体   中英

Making a complicated list comprehension conditional

Here is my current one-liner:

leader = [server.get_member(x) for x in self.rosters[server.id][clan]['members'] if discord.utils.get(server.get_member(x).roles, id="463226598351699968")]

I want to only run this if server.get_member(x) is not False . How can I add this extra logic into this list comprehension? I understand how to do a basic for in statement, but nesting it deeper than that becomes a bit confusing for me.

In general, do not sacrifice readability for the sake of writing a one-liner . If it not immediately obvious how to do it with a list-comprehension, then use a for-loop.

leader = []

for x in self.rosters[server.id][clan]['members']:
    member = server.get_member(x)
    if member and discord.utils.get(member.roles, id="463226598351699968"):
        leader.append(member)

Although, in this specific case, since you do not need x , you can use map to apply server.get_member while iterating.

leader = [m for m in map(server.get_member, self.rosters[server.id][clan]['members'])
          if m and discord.utils.get(m.roles, id="463226598351699968")]

You can't. The item in list comprehension can't be saved, so you'll have to evaluate it twice. Even if you could, don't . List comprehensions are for filtering, not for running code as side effect. It's unreadable and prone to mistakes.

In general, you can achieve the effect of a temporary variable assignment with a nested list comprehension that iterates through a 1-tuple:

leader = [m for x in self.rosters[server.id][clan]['members'] for m in (server.get_member(x),) if m and discord.utils.get(m.roles, id="463226598351699968")]

But in this particular case, as @OlivierMelançon pointed out in the comment, since the additional assignment is simply mapping a value to a function call, you can achieve the desired result with the map function instead:

leader = [m for m in map(server.get_member, self.rosters[server.id][clan]['members']) if m and discord.utils.get(m.roles, id="463226598351699968")]

While I agree with the comments suggesting you should not write this as a comprehension for readability you could try:

leader = [server.get_member(x) for x in self.rosters[server.id][clan]['members'] if discord.utils.get(server.get_member(x).roles, id="463226598351699968") if server.get_member(x)]

Similar to this answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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