10

私は自分の学校のために宝くじプログラムを作ろうとしています (私たちは経済システムを持っています)。

私のプログラムは数値を生成し、それをテキスト ファイルに保存します。ジェネレーターから数字を「引き出し」たいときは、勝者が確実に存在するようにしたいのです。

Q: Python にテキスト ファイルからランダムな行を選択させ、その番号として出力を与えるにはどうすればよいですか?

4

7 に答える 7

15

Python にテキスト ファイルからランダムな行を選択させ、その番号として出力を与えるにはどうすればよいですか?

ファイルが比較的小さいと仮定すると、おそらく次の方法が最も簡単な方法です。

import random
line = random.choice(open('data.txt').readlines())
于 2013-02-17T18:50:38.120 に答える
12

ファイルが非常に大きい場合、ファイル サイズを指定してファイル内のランダムな場所をシークし、次の完全な行を取得できます。

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()
于 2013-02-18T22:52:54.727 に答える
6
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 であると述べています。

「Pythonクックブック」の123ページより

于 2016-02-23T13:41:42.940 に答える
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]
于 2013-02-17T18:53:41.303 に答える
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 です。2 番目の数字を選択する確率は (99/100)(1/99) = 1/100 です。3 番目の数字を選択する確率は、(99/100)(98/99)(1/98) = 1/100 です。正式な証明は省略しますが、100 個の数字のいずれかを選択する確率は 1/100 です。

最初の行にカウントを格納することは厳密には必要ではありませんが、行をカウントするためだけにファイル全体を読み取らなければならないという手間を省くことができます。いずれにせよ、ファイル全体をメモリに保存して、同じ確率で任意の 1 行を選択する必要はありません。

于 2013-02-17T19:07:48.163 に答える
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

歪みは見られませんが、おそらくデータセットが小さすぎます...

于 2013-02-17T18:58:35.400 に答える
-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)
于 2013-02-20T04:13:43.413 に答える