Я пытаюсь заставить бота отправлять 10 строк текста из фактического текстового файла в 700 строк

#python #discord.py

#python #discord.py

Вопрос:

Я кодирую discord-бота с Discord.py , и я не знаю, как заставить это работать.

 @client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        for line in jeff_file:
            await ctx.send(line)
  

Файл содержит 700 слов, но я хочу, чтобы он отправил 5 или 10. Кто-нибудь может мне помочь?

Комментарии:

1. Как вы выбираете, какие из 700 слов отправлять, а какие слова не отправлять?

2. Гарантируется ли, что файл будет содержать одно слово в строке? Или может быть более одного слова в строке?

Ответ №1:

Вы можете разбить строку на слова, используя words = line.split() , подсчитать слова, а затем объединить слова в одну строку, используя text = ' '.join(words) .

Разделение строк на слова для отправки первых n слов

Следующий код отправит первые n слова файла:

 n = 5

@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        words = []
        while len(words) < n:
            line = next(jeff_file)      # will raise exception StopIteration if fewer than n words in file
            words.append(line.split())
        await ctx.send(' '.join(words[:n]))
  

Разделение строк на слова для отправки n случайных слов

Следующий код прочитает все слова из файла, затем случайным образом выберет n слов и отправит их:

 import random

n = 5

@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        words = [w for line in jeff_file for w in line.split()]
        n_random_words = random.sample(words, n)   # raises exception ValueError if fewer than n words in file
        # n_random_words = random.choices(words, k=n)  # doesn't raise an exception, but can choose the same word more than once if you're unlucky
        await ctx.send(' '.join(n_random_words))
  

Отправка первых n строк

Следующий код прочитает и отправит первые n строк из файла:

 n = 5

@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        for _ in range(n):
            line = next(jeff_file)  # will raise exception StopIteration if fewer than n lines in file
            await ctx.send(line)
  

Отправка первых n строк или меньшего количества строк, если в файле меньше n строк

 n = 5

@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        try:
            for _ in range(n):
                line = next(jeff_file)
                await ctx.send(line)
        except StopIteration:
            pass
  

Отправка n случайных строк

Следующий код прочитает весь файл и отправит n случайных строк:

 import random

n = 5

@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
        all_lines = [line for line in jeff_file]
        n_lines = random.sample(all_lines, n)  # will raise exception ValueError if fewer than n words in file
        # n_lines = random.choices(all_lines, k = n)  # doesn't raise an exception, but might choose the same line more than once
        await ctx.send(line)
  

Ответ №2:

Другие ответы работают, но если вы хотите, чтобы ваш код был проще и составлял одну строку, вы можете использовать:

 n = 5
@client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    await ctx.send(' '.join(open('Available.txt', 'r').read().split(' ')[:n]))
  

Это отправит первые n слова из документа.

Ответ №3:

Возможно, вы можете использовать enumerate и разорвать цикл следующим образом:

 @client.command(alisases = ['readfile'])
@commands.check(is_it_me)
async def jeff(ctx):
    with open('Available.txt', 'r') as jeff_file:
         jeff_lines = jeff_file.readlines()
         for i, line in enumerate(jeff_lines):
                if i == 5:
                    break
                else:
                    await ctx.send(line)
  

Комментарии:

1. Это отправляет 4 строки, а не 5. Также несколько неоднозначно в вопросе, хочет ли OP отправить 5 слов или 5 строк.

2. О, вы правы! Отредактировал цикл, спасибо. Ну, это правда, после прочтения вопроса еще раз я в замешательстве. Однако этот код отправляет 5 строк.