0

私はPythonの新機能です。繰り返しの簡素化の問題 - Pythonの関数で複数のifif文と複数のループがある場合

私はシンプルで簡潔で効率的なアルゴリズム設計とコーディングスタイルをしっかり信じています。私がPythonを学んでいるとき、私はPythonがその場で多くのことをするので、言語そのものがプログラマーにとって非常に親切であることに気付きました。これはうれしいことですが、私は自分ができる最適化について何かを深く学びたいと思っていました。そして今日、私は問題に遭遇して自分のコードを単純化しました。

以下の機能は、選択された難易度に基づいてスドーボード上に空のスポットを作成するために使用されます。

class normalSudoku(Board): 
    def __init__(self,difficulties): 
     super.__init__() 
     self.Create_Empty_Entries(difficulties) 


    def Create_Empty_Entries(self,difficulties): 
     numbers = list(range(0,9)) 
     if difficulties == "Easy": 
      for x in range(25): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
       self.holes += 1 
      return None 

     elif difficulties == "Medium": 
      for x in range(35): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

     elif difficulties == "Hard": 
      for x in range(45): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

     else: 
      for x in range(65): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

あなたはそれが非常に反復的である見ることができるように:

は、ここに私のコードです。それを簡素化するか、より効率的なコーディングスタイルを考えてください。

また、パフォーマンスとメモリ使用量に関して__init__()を呼び出すのではなく、Pythonでクラスを初期化するより良い方法がありますか? C++のように、初期化リストがあり、より洗練されています。

私が作った間違いを指摘してください。アドバイスをいただければ幸いです。ありがとう

答えて

1

変更されている唯一の事柄は、から選択されている数字の範囲ですから、数字を設定する単一の関数で難易度をその数字にマッピングすることをお勧めします。

class normalSudoku(Board): 
    def __init__(self,difficulties): 
     super.__init__() 
     self.Create_Empty_Entries(difficulties) 


    def Create_Empty_Entries(self,difficulties): 
     numbers = list(range(0,9)) 
     difficulty_values = {'Easy':25,'Medium':35, 'Hard':45, 'Default':65} 

     # check the difficulty level exists in the dict. 
     # If it does, use that value, if it doesn't then use the default value 
      difficulty = difficulty_values.get(difficulties, difficulty_values['Default']) 

      # now use that difficulty to set the numbers once. 
      for x in range(difficulty): 
      a,b = choice(numbers),choice(numbers) 
      if self.sudoku[a][b] != None: 
       self.sudoku[a][b] = None 
       self.holes += 1 
      self.holes += 1 
    return None 
+0

これは有効な点です。私はその答えを更新するつもりです! – MattWBP

+0

'dict.get'を使ってパフォーマンスが違うの?それともちょっときれいですか? –

+0

この場合はコードが少なくても、高速化は不明です。それが存在しない場合でも、そのdictキーの値を返すことが保証されているので、安全であると理解しています(デフォルトではNoneを取得します)。このようにして例外は発生しません。 – MattWBP

1

あなたは、あなたのクラスにチェック方法を追加することができます。

# add this to the class body 
def auto_increment(self, a, b): 
    if self.sudoku[a][b] != None: 
     self.sudoku[a][b] = None 
     self.holes += 1 
    self.holes += 1 
    return 

次に、あなただけの使用あなたのメソッドにパラメータを渡すことができます。

self.auto_increment(choices(number), choices(number)) 

スロットが軽減する効果的な方法ですメモリ使用量 Usage of __slots__?

+0

私は '__slots__'についてのドキュメントを読みました。私はたくさんのことを学んだ、ありがとう! –

0

1つのオプションは、コードからデータへのパラメータを入力してからデータを操作してください:

# You could source these two dicts from elsewhere, like a JSON/YAML/config file 
difficulties = { 
    Easy: { 
    size: 25 
    }, 
    Medium: { 
    size: 35 
    }, 
    Hard: { 
    size: 45 
    } 
} 

defaultDifficulty = { 
    size: 65 
} 

# ... 

def Create_Empty_Entries(self, difficultyName): 
    if difficultyName in difficulties: 
    difficulty = difficulties[difficultyName] 
    else: 
    difficulty = defaultDifficulty 

    numbers = list(range(0,9)) 
    for x in range(difficulty.size): 
    a,b = choice(numbers),choice(numbers) 
    if self.sudoku[a][b] != None: 
     self.sudoku[a][b] = None 
     self.holes += 1 
+0

他の場所からソースを入手すると、別のモジュールを作成してそこに辞書を置くことや、.txtファイルを作成してそこに書き込むことができますか?調達する際にどのキーワードを使用すればいいですか?** import **または** with **?ソーシングの利点は何ですか? –

+0

どちらも有効なオプションです。このデータをどのように生成/維持するか、またプログラムを再起動しなくても問題を再ロードできるようにするかどうかによって異なります。上記よりもはるかに複雑にするつもりがない場合は、同じモジュールにオブジェクトを置くだけで、効果的に@ MattWBPの答えになるでしょう。コードからデータを分離する利点は、両方が互いに独立して進化することができることです。コードを変更することなく範囲のサイズ(または他の将来のパラメータ)を調整することができます。また、必要に応じて、ライブの再ロードが可能になります。 – tavnab

関連する問題