Python: 快速随机拆分文件成两个文件的方法

2 投票
4 回答
3547 浏览
提问于 2025-04-16 05:14

python:有什么最快的方法可以把一个文件分成两个文件,每个文件的行数都是原文件的一半,并且这两个文件中的行是随机的?

比如说:如果文件内容是

1
2
3
4
5
6
7
8
9
10

它可以被分成:

3
2
10
9
1

4
6
8
5
7

4 个回答

1

其他版本:

from random import shuffle

def shuffle_split(infilename, outfilename1, outfilename2):
    with open(infilename, 'r') as f:
        lines = f.read().splitlines()

    shuffle(lines)
    half_lines = len(lines) // 2

    with open(outfilename1, 'w') as f:
        f.write('\n'.join(lines.pop() for count in range(half_lines)))
    with open(outfilename2, 'w') as f:
        f.writelines('\n'.join(lines))
5

你可以直接加载文件,然后对得到的列表调用 random.shuffle,最后把它分成两个文件(以下代码未经测试):

def shuffle_split(infilename, outfilename1, outfilename2):
    from random import shuffle

    with open(infilename, 'r') as f:
        lines = f.readlines()

    # append a newline in case the last line didn't end with one
    lines[-1] = lines[-1].rstrip('\n') + '\n'

    shuffle(lines)

    with open(outfilename1, 'w') as f:
        f.writelines(lines[:len(lines) // 2])
    with open(outfilename2, 'w') as f:
        f.writelines(lines[len(lines) // 2:])

random.shuffle 会在原地打乱 lines 的顺序,基本上完成了所有的工作。Python 的序列索引系统(比如 lines[len(lines) // 2:])让事情变得非常方便。

我假设这个文件不是特别大,也就是说它可以轻松放进内存里。如果文件太大,那就需要用一些更复杂的方法,可能要用到 linecache 模块来从输入文件中读取随机行号。我觉得你可能想生成两个行号的列表,使用类似上面提到的技术。

更新:把 / 改成 //,以避免在启用 __future__.division 时出现问题。

5

这种操作通常被称为“分区”。虽然没有内置的分区函数,但我找到了一篇文章:Python中的分区

根据这个定义,你可以这样做:

import random

def partition(l, pred):
    yes, no = [], []
    for e in l:
        if pred(e):
            yes.append(e)
        else:
            no.append(e)
    return yes, no

lines = open("file.txt").readlines()
lines1, lines2 = partition(lines, lambda x: random.random() < 0.5)

请注意,这样做不一定会完全把文件分成两部分,但平均来说是可以的。

撰写回答