2017-09-20 7 views
3

私はpython3が新しく、この問題を解決するためのさまざまなアプローチについて質問があります。異なるデータ構造の使用についての質問。 私の質問は、異なるサンプリング手法とのトレードオフを比較する方法です。Pythonの最適化:辞書またはリストのリストを選択する

私はこのプログラムで辞書データ構造を使ってこの問題を解決しました。それから、リストのデータ構造だけを使って書き直そうとしました。並べ替えの利点を考えようとしましたが、2つのアプローチの違いは何であるか分かりません。 2つのアプローチの間にそれほど大きな違いはないようです。

方法1.私は、方法2は、文字列形式のソーステキストを取り込み、各サブリストで の最初の要素のリストのリストを返す

私のヒストグラム内の私のヒストグラムキーと値のペアを作成するために辞書を使用します言葉であり、第二 要素は、ソーステキストに

# This program Analyze word frequency in a histogram 
# sample words according to their observed frequencies 
# takes in a source text in string format and returns a dictionary 
# in which each key is a unique word and its value is that word's 
# frequency in the source text 
import sys 
import re 
import random 
import time 

def histogram(source_text): 
    histogram = {} 
    # removing any sort of string, removing any other special character 
    for word in source_text.split(): 
     word = re.sub('[.,:;!-[]?', '', word) 

     if word in histogram: 
      histogram[word] += 1 
     else: 
      histogram[word] = 1 
    return histogram 

def random_word(histogram): 
    probability = 0 
    rand_index = random.randint(1, sum(histogram.values())) 
    # Algorithm 1 
    for (key, value) in histogram.items(): 
     for num in range(1, value + 1): 
      if probability == rand_index: 
       if key in outcome_gram: 
        outcome_gram[key] += 1 
       else: 
        outcome_gram[key] = 1 
       # return outcome_gram 
       return key 
      else: 
       probability += 1 

# Method 2 takes in a source text in string format and returns a list #of lists 
# in which the first element in each sublist is the word and the #second element is its frequency in the source texts 

    # Algorithm 2 
    # for word in histogram: 
    #  probability += histogram[word] 
    #  if probability >= rand_index: 
    #   if word in outcome_gram: 
    #    outcome_gram[word] += 1 
    #   else: 
    #    outcome_gram[word] = 1 
      # return word 


if __name__ == "__main__": 
    outcome_gram = {} 
    dict = open('./fish.txt', 'r') 
    text = dict.read() 
    dict.close() 

    hist_dict = histogram(text) 
    for number in range(1, 100000): 
     random_word(hist_dict) 
+5

早期の最適化は、など、カットした後、すべての悪...最初の小節のルートである...私は ' –

+0

ありがとうおそらく' collections.Counter(my_text_corpus)で最も読みやすいバージョンと一緒に行くお勧めします提案のために。私はその提案を感謝します。 – DataEngineer

答えて

5

どちらが読みやすくなっていますか?私は辞書のバージョンが理解しやすいと思います。また、2番目のメソッドの2タプルのリストをdictコンストラクタに渡して、最初のメソッドの出力を再現することもできます。これは、これらの2つの実装が、少なくともある程度は、おおよそ同等であるかどうかというアイデアを与えるはずです。これがパフォーマンス上の問題を引き起こしていない限り、私はあまり心配しません。

強力なのは、同じコードを5行で読みやすい形式で書くことができることです。

import re, random 
from collections import Counter 

def histogram(text): 
    clean_text = re.sub('[.,:;!-[]?', '', text) 
    words = clean_text.split() 
    return Counter(words) 

def random_word(histogram): 
    words, frequencies = zip(*histogram.items()) 
    return random.choices(words, frequencies, k=1) 
+0

これははるかに明確です.....(私は個々の単語ではなくテキスト全体でクリーナーを実行するだけですが) 'Counter(cleaner(text)) ' –

+0

@joran IIRC、文字列全体の' Counter'は –

+0

'カウンター(クリーナー(テキスト).split())'申し訳ありませんあなたは正しいです:P ...しかし、まだ各単語をきれいにするのではなく、コーパス全体を一度掃除してください。 –

2

その周波数である私は、一般的に、あなたの問題を解決するためにしばしば優れている、上記Joranビーズリーさんのコメントに同意した後、戻って、後で効率のためにリファクタリングします。

ヒストグラムを操作する場合は、コレクションモジュール内でCounterをチェックすることをおすすめします。コレクションモジュール全体は本当に素晴らしいですし、多くの便利なコンテナがあります。

もう1つのクールなモジュールはTimeitモジュールで、コードスニペットで小さなタイミング実験を実行できます。実行速度は、必ずしもプログラムの制御ではない多くの要因に依存します。

関連する問題