【问题标题】:Python print random line from file without repeatPython从文件中打印随机行而不重复
【发布时间】:2020-01-16 02:26:48
【问题描述】:

我有一个从文本文件中打印随机行的小程序。我想将已经选择的行保存在列表或其他内容中,这样下次就不会重复了。

示例

text_database.txt

  1. 这是一行
  2. 这是另一行
  3. 这是一条测试线
  4. 太糟糕了

这是一个显示输出是随机的并且程序重复行的示例——它不是终端中的直接输出:

This is a line
That sucks
That sucks
That sucks
This is a line

我的代码:

# Variable for text file
text_database = './text_database.txt'

...

with open (text_database) as f:
    lines = f.readlines()
    print(random.choice(lines))

我尝试了什么:

with open (text_database) as f:
    lines_list = []
    lines = f.readlines()
    random_tmp = random.choice(lines)
    if random_tmp not in lines_list:
        lines_list.append(random_tmp)
        print(random_tmp)

它不起作用,我需要帮助。谢谢各位。

【问题讨论】:

  • 这是在您运行文件时从文件中随机打印一行然后程序结束吗?为了清楚起见,您想保存在程序的不同执行中打印了哪些行?编辑:否则我不明白为什么它打印 5 次,不确定 elif 被包围的是什么
  • 这是一个电报机器人,消息将在热敏打印机上打印。所以程序正在运行空洞时间,并在程序运行时从文件中打印行。第一个代码块效果很好。是的,我想保存已打印的行,因此程序下次将选择另一行。输出只是为了向您显示程序重复了这些行。这不是直接输出。它只打印一次。很抱歉造成混乱。
  • 您没有更新lines_list,这是您问题的根源吗?作为set,而不是list,它会更有效。

标签: python python-3.x file random text


【解决方案1】:
from random import sample

file_name = "text_database.txt"
lines = open(file_name, "r").read().splitlines()

for line in sample(lines, k=len(lines)):
    print(line)

我使用.read().splitlines() 而不是.readlines() 来清除每行的尾随空格(换行符)。我也可以这样做:

lines = [line.rstrip("\n") for line in open(file_name, "r")]

这是文档中对random.sample 的描述:

返回从总体中选择的唯一元素的 k 长度列表 顺序。用于无放回的随机抽样。

或者,您可以打乱您的行列表,然后对其进行迭代。

编辑 - 我想我现在明白了。怎么样?

def main():

    from random import shuffle

    file_name = "text_database.txt"
    lines = open(file_name, "r").read().splitlines()
    shuffle(lines)

    sentinel = object()

    def command_random():
        try:
            line = lines.pop()
        except IndexError:
            print("There are no more lines in the file!")
        else:
            print(line)

    def command_quit():
        nonlocal sentinel
        sentinel = None

    commands = {
        "random": command_random,
        "quit": command_quit
    }

    while sentinel is not None:
        user_input = input("Please enter a command: ")
        command = commands.get(user_input)
        if command is None:
            continue
        command()

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

【讨论】:

  • 你为什么用splitlines(),你为什么用sample(...?请多解释一下。
  • 感谢您的回答。该程序不会重复这些行。问题是,它打印文件中的所有行,但我只想从文件中打印一行而不重复。
  • 当你说“没有重复”时,你的意思是,你运行程序一次,它打印一个随机行,你再次运行程序,它打印一个不同的随机行(一个还没有被在程序的先前执行中打印)?
  • 不,我在上面的 cmets 中描述了它。这是一个电报机器人,程序正在运行空档时间。我想在打开命令时从文件中打印一行。在这种情况下/random。下次运行命令时,我想从文本文件中打印另一行。不一样。
【解决方案2】:

这是一个非常混乱的解决方案,但我事先已经测试过了


f = open(text_database, "r")

list = []
list_of_nums = []

for i in f:
    list.append(i)

elif command == '/random':

    randomNum = random.randint(0, len(list) - 1)

    def reRun():
        global randomNum
        for i in list_of_nums:

            if randomNum == i:
                randomNum = random.randint(0, len(list) - 1)
                reRun()


    reRun()
    list_of_nums.append(randomNum)

    print(list[randomNum])

这段代码的含义是遍历 f 中的所有行并将它们放在一个列表中。比它选择一个介于 0 和列表长度之间的随机数并打印对应于该数字的随机行

希望这会有所帮助!并欢迎堆栈溢出

【讨论】:

  • 感谢您的回答。如果我是对的,程序将打印一个可能重复的随机行 - 我是对的?
  • 抱歉,我重新阅读了您的问题,我现在知道您想要什么,请给我几分钟,我会编辑它
  • 我已经解决了这个问题,但是现在编辑帖子真的很混乱
【解决方案3】:
elif command == '/random':
    with open (text_database) as f:
        lines = f.readlines()

    while len(lines)>0:
        max_int = len(lines)-1 #update the len each loop as we remove one each time
        print(lines.pop(random.randint(0, max_int))) #pop a random value from the list

【讨论】:

  • 感谢您的回答。问题是,程序打印文件中的所有行而不重复。但我只想打印一行。
【解决方案4】:

您的代码的问题是,如果您遇到已经显示的行,您只需返回并且什么都不做。

你可以对你的代码做一些小的调整是选择一个新的随机行直到你找到一个你还没有选择的。这是使用while 块完成的:

# Variable for text file
text_database = './text_database.txt'
#List of already chosen lines
lines_list = []

# Elif instruction for random lines from file
elif command == '/random':
    with open (text_database) as f:
        lines = f.readlines()
        random_tmp = random.choice(lines)
        #while line has been chosen already, try to chose another one
        while random_tmp in lines_list:
            random_tmp = random.choice(lines)
        lines_list.append(random_tmp)
        print(random_tmp)

请注意,此代码有一些限制:

  • 一旦选择了所有行,循环将永远运行
  • 记住已选择的文本行可能会消耗内存,但您可以记住已选择的行的索引。

【讨论】:

    【解决方案5】:

    试试这个解决方案,它每次只打印一个随机行

    import random
    text_database = './text_database.txt'
    lines_list = []
    with open (text_database) as f:
        lines = f.readlines()
        lines_list.append(lines)
    for item in lines_list:
        rand_item = item[random.randrange(len(item))]
    print(rand_item)
    

    【讨论】:

    • 感谢您的回答。但程序打印行重复。
    • 你能解释一下你所说的重复吗?
    【解决方案6】:

    嘿,这有点不那么凌乱,并且具有您要求的所有功能

    f = open(text_database, "r")
    
    list = []
    
    for i in f:
        list.append(i)
    
    elif command == '/random':
    
        random.shuffle(list)
    
        for i in list:
    
            print(i)
    

    这会获取文件中的所有行,并使用random.shuffle 中内置的 python 将它们打乱,这些行不会重复,而且相当有效

    【讨论】:

      猜你喜欢
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 2021-01-02
      • 2018-03-16
      • 1970-01-01
      • 2015-01-11
      相关资源
      最近更新 更多