1

我有这行代码:

bitext = [[sentence.strip().split() 
           for sentence in pair if len(sentence) < 100] 
          for pair in zip(open(c_data), open(e_data))[:opts.num_sents]]

c_data是带有中文句子
e_data的文件 是带有英文句子的文件。
bitext应该是一个包含成对的英文和中文句子的列表,它们是彼此的翻译。

由于两个数据文件都很大,
我想通过只考虑低于一定长度的句子来降低代码的复杂性。长度以字符为单位。

例如,
我在这里将长度指定为100. :opts.num_sents是一个变量,表示应考虑数据文件中的句子数量。

问题/错误
如果一个中文句子是 95 个字符,而一个英文句子是 105 个字符,bitext则只会用中文句子更新。
但我希望代码只添加一对句子,如果它们都在规定的长度之下。
我该怎么做呢?

4

3 回答 3

2

是时候打破这个单行了:

def tokenize(sentence):
    return sentence.strip().split()

def sentence_pairs(c_data, e_data):
    for chinese, english in zip(open(c_data), open(e_data))[:opts.num_sents]:
        if len(chinese) < 100 and len(english) < 100
            yield tokenize(chinese), tokenize(english)

yield关键字变成了一个生成器sentence_pairs。如果只对结果进行迭代,这是一种更简单的编写方式:

def sentence_pairs(c_data, e_data):
    results = []

    for chinese, english in zip(open(c_data), open(e_data))[:opts.num_sents]:
        if len(chinese) < 100 and len(english) < 100
           results.append((chinese, english))

    return results
于 2013-03-04T10:29:39.600 回答
1

首先,重写您的代码,使其易于理解!列表推导很棒,但是当它们消失在页面末尾时,它们会变得非常难以理解。

bitext = [[sentence.strip().split() for sentence in pair if len(sentence) < 100] for pair in zip(open(c_data), open(e_data)) [:opts.num_sents]]

与(基本上)相同

bitext = []
for i, pair in enumerate(zip(open(c_data), open(e_data))):
    if i < opts.num_sents:
        sentence_pair = []
        for sentence in pair:
            if len(sentence) < 100:
                sentence_pair.append(sentence.strip().split())
        if len(sentence_pair) > 1:  # ie both sentences are < 100
            bitext.append(sentence_pair)

现在,您要添加带有 length 的句子> 100。你可以看到这条线

if len(sentence) < 100:

正在防止这种情况发生,因此请更改 100。

于 2013-03-04T10:27:55.550 回答
1

我认为您正在尝试做的可能是这样的:

bitext = [[sentence.strip().split() for sentence in pair] 
  for pair in zip(open(c_data), open(e_data))[:opts.num_sents] if all(len(s) < 100 for s in pair)]

这在列表理解中非常难看,我建议您使用此处建议的其他方法之一。

于 2013-03-04T10:30:51.857 回答