2012-03-07 2 views
5

당신이 minecraft를 해본 적이 있다면 다음과 같은 의미가 있습니다. 많은 분들이 그러하니 최선을 다해 설명 드리겠습니다.파이썬 재귀 적 데이터 읽기

minecraft recipe의 flatfile에서 모든 minecraft 아이템을 만드는 단계를 찾을 수있는 재귀 함수를 작성하려고합니다. 이 하나는 정말 난처한 있습니다.

플랫 파일은 다소 길기 때문에 this 요점에 포함 시켰습니다.

def getRecipeChain(item, quantity=1): 
    #magic recursive stuffs go here 

그래서 기본적으로 나는 다음 첫 번째 레시피를 찾아 볼 그래서 당신이 어떤 조리법으로 항목을 얻을 때까지 첫 번째 조리법의 모든 구성 요소에 대한 조리법을보고해야합니다. 나는 목록에 조리법을 추가 할 때마다 내가 그래서 여기.

을 공예품에 어떤 순서에서의 명령어 세트의 종류를 얻을 내가 지금 가지고있는 기능입니다

합니다 (하나가 작동하지 않습니다)
def getRecipeChain(name, quantity=1): 
    chain = [] 

    def getRecipe(name1, quantity1=1): 
     if name1 in recipes: 
      for item in recipes[name1]["ingredients"]["input"]: 
       if item in recipes: 
        getRecipe(item, quantity1) 
       else: 
        chain.append(item) 

    getRecipe(name, quantity) 
    return chain 

여기 제가 가장 이상적인 결과물입니다. 항목 이름과 수량이 저장된 사전입니다.

>>> getRecipeChain("solar_panel", 1): 
{"insulated_copper_cable":13, "electronic_circuit":2, "re_battery":1, "furnace":1, "machine":1, "generator":1, "solar_panel":1} 

그럼 어떻게해야합니까?

내가 당신을 위해 일하는 것을 요구하는 것은 여기에 눈살을 찌푸리게됩니다. 그래서 이것이 당신에게 조금 너무 가깝다 고 느끼면, 저를 위해 코딩을하고 있습니다. 그렇게 말하십시오.

+2

그냥 말,하지만 샘플 출력은 옳지 않다 생각 ... – PearsonArtPhoto

+0

그것은 잘못? – giodamelio

+2

글쎄 insulated_copper_cable은 기본 항목이 아닙니다. 그렇습니까? electronic_circuit도 아닙니다. 복잡한 재료가 아니라 기본 재료를 얻고 싶습니다. – PearsonArtPhoto

답변

3

이 우아 collections.Counter를 사용하여 해결할 수 있습니다 : 어떤 방법으로

from collections import Counter 

def getRecipe(name, quantity=1): 
    if not name in recipes: return Counter({name: quantity}) 

    subitems = recipes[name]["ingredients"]["input"] 
    return sum((getRecipe(item, quantity) for item in subitems), 
      Counter()) 

print repr(dict(getRecipe("solar_panel"))) 
# => {'copper': 39, 'refined_iron': 10, 'glass': 3, 
#  'rubber': 78, 'cobblestone': 8, 'tin': 4, 
#  'coal_dust': 3, 'nothing': 10, 'redstone': 6} 
1

문제는 2 배라고 생각합니다. 우선 getRecipe()에 대한 재귀 호출에서 항목을 체인에 추가해야합니다. 두 번째로, 나는 두 가지 기능이 불필요하게 복잡한 것을 생각합니다. 나는 내면의 사람이해야한다고 생각합니다. 이 같은 것이 당신이 찾고있는 것입니다. 테스트를 해보지는 않았지만 올바른 방향으로 시작할 수있을만큼 근접해야합니다.

def getRecipe(name, quantity=1): 
    chain=[]; 
    if name in recipes: 
     for item in recipes[name]["ingredients"]["input"]: 
      if item in recipes: 
       chain.append(getRecipe(item, quantity)) 
      else: 
       chain.append(item) 
    return chain 

편집 : 의견은 파이썬 지식이 부족하기 때문에 더 나은 해결책입니다. 또한 지원

from collections import Counter 
def getRecipe(name, quantity=1, count=Counter()): 
    if name in recipes: 
     for item in recipes[name]["ingredients"]["input"]: 
      if item in recipes: 
       getRecipe(item, quantity,counter) 
      else: 
       counter[item]+=quantity 
    return counter 
+0

원하는 출력은 dict이므로 chain.append 대신 * chain.setdefault (item, 0) + = quantity * –

+0

@campos를 사용해야합니다. @campos : 예상대로 작동하지 않으며 값이 증가하지 않습니다. 'defaultdict (int)'는 이상적인 데이터 구조입니다. –

+0

오케이, 그건 사실이에요. –