2013-03-04 108 views
1

我有這行代碼:Python的if語句

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將只與中國句子進行更新。
但我希望代碼只添加一對句子,如果他們都在規定的長度。
我該怎麼做?

+0

很抱歉,您的問題很難理解,您究竟在做什麼?您的問題標題似乎與您的問題沒有任何關係。 – 2013-03-04 10:24:56

+0

這不是for循環中的* if語句* - 它是[list comprehension](http://www.youtube.com/watch?v=pShL9DCSIUw)。 – 2013-03-04 10:26:27

+0

忘記標題,我不知道這被稱爲列表理解。我的問題是關於如何處理其中一個滿足'len(句子)<100'的對,但另一個不滿足。 – Johanna 2013-03-04 10:44:07

回答

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) 

現在,要與長度> 100添加句子。你可以看到該行

if len(sentence) < 100: 

是防止這一點,所以改變100

+0

我認爲問題不是添加長度大於100的句子。 OP正在試圖問如何在列表中添加一對句子,如果它們都滿足len <100 – Dhara 2013-03-04 10:33:16

+0

的標準問題是我總是想要添加兩個句子或者不添加(它們是彼此的翻譯,所以只添加一個是沒有意義的)。如果其中一個句子的長度<100,另一個長度> 100,那麼長度<100的句子的長度不應該添加,儘管它確認了代碼。我現在讓自己更清楚了嗎? – Johanna 2013-03-04 10:41:39

+0

不是。上面的代碼將添加兩個句子,如果它們符合或不符合(忽略Dhara的評論)。 – danodonovan 2013-03-04 10:58:24

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 
+0

您還應該考慮添加一個解釋爲什麼這會起作用。 – Dhara 2013-03-04 10:34:27

+0

@Dhara:沒有太多解釋。代碼是詳細的。 – Blender 2013-03-04 10:38:35

+0

如果OP不理解列表理解(基於問題標題),我假設他也沒有得到生成器。無論如何,我upvoted :) – Dhara 2013-03-04 10:41:04

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)] 

這是一個列表理解很醜陋,我建議你使用這裏建議的其他方法之一。

+0

是的,這就是我的意思!但是,如果全部(len(s)<100)都添加空列表,你知道如何阻止這種情況發生嗎? – Johanna 2013-03-04 11:16:12

+0

@Johanna是的,移動條件。我將編輯。 – 2013-03-04 12:25:38