0

저는 Python을 처음 접했습니다.반복적 인 문제를 단순화하는 데 어려움이 있습니다 - Python의 함수에서 elif 문과 다중 루프가 여러 개있는 경우

저는 간단하고 간결하며 효율적인 알고리즘 디자인과 코딩 스타일을 확고히 믿습니다. 파이썬을 배우면서 파이썬이 많은 일을하고 있다는 사실을 깨달았습니다. 그래서 언어 자체가 프로그래머들에게 매우 친숙합니다. 이것은 좋은 일이지만, 내가 할 수있는 최적화 나 코딩 할 습관을 깊게 배우고 싶었습니다. 그리고 오늘은 문제가 생겨서 코드를 단순화했습니다.

다음 기능은 선택한 난이도에 따라 스도쿠 보드에 빈 스폿을 만드는 데 사용됩니다.

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__()을 호출하는 대신 파이썬에서 클래스를 초기화하는 더 좋은 방법이 있습니까? C++과 마찬가지로 초기화 목록이 더 깨끗하고 빠릅니다.

내가 실수 한 점을 지적하십시오. 모든 조언을 크게 주시면 감사하겠습니다. 고마워요

답변

1

변경되는 유일한 숫자 이후부터 선택되는 숫자의 범위입니다, 난 그 어려움이 번호를 설정 한 번호를 설정하는 하나의 기능에서 사용하는 dict를 만드는 것이 좋습니다.

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

하나의 옵션은 코드에서 데이터까지의 매개 변수를 확인한 다음 데이터를 조작하십시오.

# 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 ** 또는 ** **입니다. 그리고 소싱의 이점은 무엇입니까? –

+0

둘 다 유효한 옵션입니다. 이 데이터를 생성/유지하려는 방법과 프로그램을 다시 시작하지 않고 문제를 재로드 할 수 있는지 여부에 따라 다릅니다. 위의 것보다 훨씬 더 복잡하게 만들 계획이 없다면,이 모듈을 객체로 유지하는 것이 효과적 일 것입니다. 이것은 MattWBP의 대답입니다. 코드에서 데이터를 분리하는 이점은 둘 다 서로 독립적으로 진화 할 수 있다는 것입니다.코드를 변경하지 않고도 범위 크기 (또는 다른 미래 매개 변수)를 조정할 수 있습니다. 또한 필요할 경우 실시간으로 문제를 다시로드 할 수 있습니다. – tavnab