如何从文本文件中选择随机行

时间:2013-02-17 18:48:47

标签: python file random python-3.3

我正在为我的学校制作一个彩票计划(我们有一个经济系统)。

我的程序生成数字并将其保存到文本文件中。当我想从我的发电机中“拉出”数字时,我希望它确保有一个胜利者。

问:我如何让Python从文本文件中选择一个随机行并将输出作为该数字?

7 个答案:

答案 0 :(得分:15)

  

如何让python从我的文本文件中选择一个随机行并将输出作为该数字?

假设文件相对较小,以下可能是最简单的方法:

import random
line = random.choice(open('data.txt').readlines())

答案 1 :(得分:10)

如果文件非常大 - 您可以在给定文件大小的文件中寻找随机位置,然后获得下一个完整的行:

import os, random 
def get_random_line(file_name):
    total_bytes = os.stat(file_name).st_size 
    random_point = random.randint(0, total_bytes)
    file = open(file_name)
    file.seek(random_point)
    file.readline() # skip this line to clear the partial line
    return file.readline()

答案 2 :(得分:5)

def random_line():
    line_num = 0
    selected_line = ''
    with open(filename) as f:
        while 1:
            line = f.readline()
            if not line: break
            line_num += 1
            if random.uniform(0, line_num) < 1:
                selected_line = line
    return selected_line.strip()

虽然这里给出的大部分方法都有效,但它们倾向于将整个文件一次加载到内存中。但不是这种方法。因此,即使文件很大,这也行得通。

乍一看,这种方法并不是很直观。这背后的定理指出,当我们看到N条线存在恰好1 / N的概率时,到目前为止它们中的每一条都被选中。

From Page no 123 of 'Python Cookbook

答案 3 :(得分:3)

脱离我的头顶:

import random
def pick_winner(self):
    lines = []
    with open("file.txt", "r") as f:
        lines = f.readlines();
    random_line_num = random.randrange(0, len(lines))
    return lines[random_lines_num]

答案 4 :(得分:3)

稍微修改输入文件(存储第一行中的项目数),您可以统一选择一个数字而无需先将整个文件读入内存。

import random
def choose_number( frame ):
    with open(fname, "r") as f:
        count = int(f.readline().strip())
        for line in f:
            if not random.randrange(0, count):
                return int(line.strip())
            count-=1

假设您有100个号码。选择第一个数字的概率是1/100。选择第二个数字的概率是(99/100)(1/99)= 1/100。选择第三个数字的概率是(99/100)(98/99)(1/98)= 1/100。我将跳过正式证明,但选择100个数字中的任何一个的几率是1/100。

在第一行中存储计数并不是绝对必要的,但它可以省去必须读取整个文件以计算行数的麻烦。无论哪种方式,您都不需要将整个文件存储在内存中以选择具有相同概率的任何单行。

答案 5 :(得分:2)

另一种方法:

import random, fileinput

text = None
for line in fileinput.input('data.txt'):
    if random.randrange(fileinput.lineno()) == 0:
        text = line
print text

分布:

$ seq 1 10 > data.txt

# run for 100000 times
$ ./select.py > out.txt

$ wc -l out.txt 
100000 out.txt

$ sort out.txt | uniq -c
  10066 1
  10004 10
  10023 2
   9979 3
   9926 4
   9936 5
   9878 6
  10023 7
  10154 8
  10011 9

我没有看到倾斜,但数据集可能太小......

答案 6 :(得分:-1)

我看了一个python教程并找到了这个片段:

def randomLine(filename):
#Retrieve a  random line from a file, reading through the file once
        fh = open("KEEP-IMPORANT.txt", "r")
        lineNum = 0
        it = ''

        while 1:
                aLine = fh.readline()
                lineNum = lineNum + 1
                if aLine != "":
                        #
                        # How likely is it that this is the last line of the file ? 
                        if random.uniform(0,lineNum)<1:
                                it = aLine
                else:
                        break
        nmsg=it
        return nmsg
        #this is suposed to be a var pull = randomLine(filename)