Ale*_*lli 63
不是内置的,但R(3.4.2)Knuth的"计算机编程艺术"中的算法(Waterman的"水库算法")很好(在一个非常简化的版本中):
import random
def random_line(afile):
line = next(afile)
for num, aline in enumerate(afile, 2):
if random.randrange(num): continue
line = aline
return line
Run Code Online (Sandbox Code Playgroud)
所述num, ... in enumerate(..., 2)迭代器产生的序列2,3,4 ...的randrange因此将0的概率为1.0/num-这与我们必须替换当前选定的行(被引用的算法的样本大小1的特殊情况的概率- 请参阅Knuth的书中的正确性证明==当然我们也是在一个足够小的"水库"以适应记忆的情况下; - ))......以及我们这样做的概率.
Ton*_*nen 29
import random
lines = open('file.txt').read().splitlines()
myline =random.choice(lines)
print(myline)
Run Code Online (Sandbox Code Playgroud)
对于非常长的文件:根据文件的长度在文件中寻找随机位置,并在位置(或换行符和文件结尾)后找到两个换行符.如果原始搜索位置<100,如果我们在最后一行内部结束,则在文件开头之前或之后再做100个字符.
然而,这是复杂的,因为文件是iterator.So使它列表并采取random.choice(如果你需要很多,使用random.sample):
import random
print(random.choice(list(open('file.txt'))))
Run Code Online (Sandbox Code Playgroud)
Nic*_*lfi 10
虽然我迟到了四年,但我认为我有最快的解决方案.最近我写了一个名为linereader的python包,它允许你操作文件句柄的指针.
以下是使用此包获取随机行的简单解决方案:
from random import randint
from linereader import dopen
length = #lines in file
filename = #directory of file
file = dopen(filename)
random_line = file.getline(randint(1, length))
Run Code Online (Sandbox Code Playgroud)
第一次这样做是最糟糕的,因为linereader必须以特殊格式编译输出文件.完成此操作后,无论文件大小如何,linereader都可以快速访问文件中的任何行.
如果您的文件非常小(小到足以容纳MB),那么您可以替换dopen为copen,并且它在内存中创建文件的缓存条目.这不仅更快,而且在文件加载到内存时获得文件内的行数; 它是为你完成的.您需要做的就是生成随机行号.这是一些示例代码.
from random import randint
from linereader import copen
file = copen(filename)
lines = file.count('\n')
random_line = file.getline(randint(1, lines))
Run Code Online (Sandbox Code Playgroud)
我真的很开心,因为我看到有人可以从我的包装中受益!对不起,对于死的答案,但该包肯定可以应用于许多其他问题.
这取决于"太多"开销是什么意思.如果可以将整个文件存储在内存中,那么就像
import random
random_lines = random.choice(open("file").readlines())
Run Code Online (Sandbox Code Playgroud)
会做的伎俩.
如果您不想使用f.read()或将整个文件加载到 RAM 中f.readlines(),您可以通过以下方式获取随机行:
import os
import random
def get_random_line(filepath: str) -> str:
file_size = os.path.getsize(filepath)
with open(filepath, 'rb') as f:
while True:
pos = random.randint(0, file_size)
if not pos: # the first line is chosen
return f.readline().decode() # return str
f.seek(pos) # seek to random position
f.readline() # skip possibly incomplete line
line = f.readline() # read next (full) line
if line:
return line.decode()
# else: line is empty -> EOF -> try another position in next iteration
Run Code Online (Sandbox Code Playgroud)
PS:是的,这是 Ignacio Vazquez-Abrams 在上面的答案中提出的,但是 a)他的答案中没有代码,b)我自己想出了这个实现;它可以返回第一行或最后一行。希望它对某人有用。
但是,如果您关心分发,那么此代码不适合您。
Alex Martelli 的答案的稍微改进版本,它处理空文件(通过返回一个default值):
from random import randrange
def random_line(afile, default=None):
line = default
for i, aline in enumerate(afile, start=1):
if randrange(i) == 0: # random int [0..i)
line = aline
return line
Run Code Online (Sandbox Code Playgroud)
这种方法可用于使用O(n)时间和O(1)空间从任何迭代器中获取随机项。
| 归档时间: |
|
| 查看次数: |
59905 次 |
| 最近记录: |