Как выбрать случайную строку из текстового файла
Я пытаюсь сделать программу лотерея для моей школы (у нас есть экономическая система).
моя программа генерирует числа и сохраняет их в текстовый файл. Когда я хочу "вытащить" числа из своего генератора, я хочу, чтобы он гарантировал, что есть победитель.
Q: Как Python выбрать случайную строку из моего текстового файла и дать мой вывод как это число?
7 ответов
как python выбрать случайную строку из моего текстового файла и дать мой вывод как это число?
предполагая, что файл относительно мал, возможно, самый простой способ сделать это:
import random
line = random.choice(open('data.txt').readlines())
Если файл очень большой - вы можете искать случайное местоположение в файле с учетом размера файла, а затем получить следующую полную строку:
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()
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, что каждый из них выбран до сих пор.
С небольшой модификацией входного файла (сохраните количество элементов в первой строке), вы можете выбрать число равномерно без необходимости сначала читать весь файл в память.
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.
Не обязательно хранить счетчик в первой строке, но это избавляет вас от необходимости читать весь файл только для подсчета строк. В любом случае вам не нужно хранить весь файл в памяти, чтобы выбрать любую строку с равной вероятностью.
С моей макушки:
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]
другой подход:
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
Я не вижу перекосы, но, возможно, набор данных слишком мал...
Я видел учебники 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)