使用Python中的随机模块选择时出错

时间:2012-07-27 16:32:53

标签: python random error-handling

我正在尝试基于输入数据集构建随机数据集。 输入数据集由856471行组成,每行中有一对由制表符分隔的值。 随机数据集中的任何条目都不能等于输入数据集中的任何条目,这意味着:

如果第1行中的对是“Protein1 Protein2”,则随机数据集不能包含以下对:

  • “Protein1 Protein2”
  • “Protein2 Protein1”

为了达到这个目的,我尝试了以下方法:

data = infile.readlines()
ltotal = len(data)
for line in data:
    words = string.split(line)

init = 0
while init != ltotal:
    p1 = random.choice(words)
    p2 = random.choice(words)
    words.remove(p1)
    words.remove(p2)
    if "%s\t%s\n" % (p1, p2) not in data and "%s\t%s\n" % (p2, p1) not in data:
        outfile.write("%s\t%s\n" % (p1, p2))

但是,我收到以下错误:

Traceback (most recent call last):   File
"C:\Users\eduarte\Desktop\negcreator.py", line 46, in <module>
    convert(indir, outdir)   File "C:\Users\eduarte\Desktop\negcreator.py", line 27, in convert
    p1 = random.choice(words)   File "C:\Python27\lib\random.py", line 274, in choice
    return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
IndexError: list index out of range

我很确定这会奏效。我究竟做错了什么? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

为循环中的每一行覆盖变量words

for line in data:
    words = string.split(line)

这很可能不是你想要的。

此外,您的while循环是一个无限循环,最终会消耗wordsrandom.choice()没有任何选择。

编辑:我的猜测是你有一个由制表符分隔的单词对的文件,每行都有一对,你试图从所有单词形成随机对,只写那些输出文件中的随机对,不会出现在原始文件中。这是一些代码:

import itertools
import random
with open("infile") as infile:
    pairs = set(frozenset(line.split()) for line in infile)
words = list(itertools.chain.from_iterable(pairs))
random.shuffle(words)
with open("outfille", "w") as outfile:
    for pair in itertools.izip(*[iter(words)] * 2):
        if frozenset(pair) not in pairs:
            outfile.write("%s\t%s\n" % pair)

注意:

  1. 一对单词由frozenset表示,因为顺序无关紧要。

  2. 我使用set对所有对来测试一对是否在常量时间内在集合中。

  3. 我不是反复使用random.choice(),而是只对整个列表进行一次洗牌,然后成对迭代它。这样,我们不需要从列表中删除已经使用过的单词,因此效率更高。 (这个改变是前一个改变了从O(n²)到O(n)的方法的算法复杂性。)

  4. 表达式itertools.izip(*[iter(words)] * 2)是一种常见的Python成语,可以成对迭代words,以防你还没遇到过。

  5. 代码仍未经过测试。