0

I am working on a discord bot and returning a list of item. Unfortunately, if the list exceeds 25 items, it throws an error. I want break the loop after 25 loops. Below is a sample of code provided in the discord.py documentation; the for loop is a single line and does not work if I try to modify it:

async def fruit_autocomplete(
interaction: discord.Interaction,
current: str,
) -> List[app_commands.Choice[str]]:
    fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry']
    return [
        app_commands.Choice(name=fruit, value=fruit)
        for fruit in fruits if current.lower() in fruit.lower()
    ]

1 Answers1

1

Use the itertools.islice to take first N results from a generator (...):

async def fruit_autocomplete(
interaction: discord.Interaction,
current: str,
) -> Iterable[app_commands.Choice[str]]:
    fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry']
    return itertools.islice(
        (app_commands.Choice(name=fruit, value=fruit)
        for fruit in fruits if current.lower() in fruit.lower())
    , 25)

If desiring a List as result, wrap above return with list(...).


With just a list, slice with [:N]:

async def fruit_autocomplete(
interaction: discord.Interaction,
current: str,
) -> List[app_commands.Choice[str]]:
    fruits = ['Banana', 'Pineapple', 'Apple', 'Watermelon', 'Melon', 'Cherry']
    current = current.lower()
    return [app_commands.Choice(name=f, value=f)
            for f in fruits if current in f.lower()][:25]
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53
  • `itertools.islice` will return generator, not list and in both cases they will need to create the full list first and then convert to generator or slice it – buran Jan 19 '23 at 18:25
  • @buran yes, good point. I updated answer as I realize this too. – rv.kvetch Jan 19 '23 at 18:25
  • also, if they will return generator, why use isllce, just return generator expression/generator, instead of list – buran Jan 19 '23 at 18:26
  • right, but from what I gather they only want the first 25 results from the generator expression – rv.kvetch Jan 19 '23 at 18:27
  • @buran You're wrong ("in both cases they will need to create the full list first"). When using `islice(generator, 25)`, only 25 `app_commands.Choice` objects will be created. When using a list comprehension, potentially more would be created (if `fruits` was larger). This distinction is important when it's costly to fetch these items. – Niccolo M. Jan 19 '23 at 18:33
  • @NiccoloM., I agree - ma bad, I overlooked that there is generator inside the islice. However, you are wrong too :-) - they will create generator and no app_commands.Choice objects will be created until they consume the generator at later stage. – buran Jan 19 '23 at 18:35