我想爲我的學校(我們有一個經濟體系)製作一個彩票計劃。如何從文本文件中選擇一條隨機線
我的程序生成數字並將其保存到文本文件中。當我想從生成器中「拉出」數字時,我希望它確保有一個贏家。
問:我如何讓Python從我的文本文件中選擇一個隨機線並將該輸出作爲該數字輸出?
我想爲我的學校(我們有一個經濟體系)製作一個彩票計劃。如何從文本文件中選擇一條隨機線
我的程序生成數字並將其保存到文本文件中。當我想從生成器中「拉出」數字時,我希望它確保有一個贏家。
問:我如何讓Python從我的文本文件中選擇一個隨機線並將該輸出作爲該數字輸出?
How do I have python select a random line out of my text file and give my output as that number?
假設該文件是比較小的,以下是可能做到這一點最簡單的方法:
import random
line = random.choice(open('data.txt').readlines())
關閉我的頭頂:
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
我沒有看到skewnes但也許數據集太小......
這扭曲了對文件中早先出現的數字的選擇。 – chepner 2013-02-17 19:00:46
@chepner - 查看更新。沒有看到歪斜... – 2013-02-17 19:38:10
它的傾斜有點不同於我的預期(我沒有仔細看過你的代碼)。你基本上是從1到10中選擇一組數字,然後輸出最大的數字。所以,儘管選擇1作爲集合的一部分的可能性更大(事實上,它總是*是集合的一部分,因爲'randrange(0,1)'將總是返回0),它將永遠不會被返回除非*不選*其他號碼。注意你的分佈看起來像一個倒轉的鐘形曲線,極端數字顯着地選擇了中間數字。 – chepner 2013-02-17 20:12:50
有輕微的修改輸入文件(存儲在第一線的項目數),則可以無需首先將整個文件讀入內存,統一選擇一個數字。
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。
將計數存儲在第一行並不是必須的,但它可以節省讀取整個文件以計算行數的麻煩。無論哪種方式,您都不需要將整個文件存儲在內存中,以相同的概率選擇任何一行。
,無需爲每行調用「random.randrange」。只需隨機選擇行號並前進到該行。 – mata 2013-09-09 00:02:53
如果該文件是非常大的 - 你可以尋求到指定的文件大小的文件在隨機位置,然後得到下一個完整行:
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()
該方法會縮短選擇的機率,因此如果您真的想讓您的隨機生成器以相同的概率選擇每一行,這不是一個好的選擇。 – mata 2013-09-08 23:57:04
它也不會返回第一行,並且在random_point位於最後一行時不會返回任何行。 – 2017-06-13 12:53:38
我看到一個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)
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的概率,他們每個都被選中。
出於某種原因,當我嘗試你的方法我收到以下消息 _italic_ ** **大膽'回溯(最近通話最後一個): 文件「/用戶/ pilotkid /文檔/彩票。 py「,第338行,在 line = random.choice(open('KEEP-IMPORANT.txt')。readlines()) 文件」/System/Library/Frameworks/Python.framework/Versions/2.7/lib/ python2.7/random.py「,第274行,選擇 return seq [int(self.random()* len(seq))]#如果seq爲空,則引發IndexError IndexError:列表索引超出範圍 註銷 [處理完成] ' –
2013-02-18 22:07:03
文件是否爲空? – NPE 2013-02-19 06:26:49
事實證明它不是在製作文件。奇怪的感謝你所有的時間 – 2013-02-20 03:59:40