2012-03-07 83 views
5

如果您曾经玩过Minecraft,以下将会更有意义。由于你们许多人都没有,我会尽力尽我所能解释它Python递归数据读取

我想写一个递归函数,可以找到从minecraft的食谱平面文件制作任何我的世界物品的步骤。这一个让我真的很难过。

Flatfile有点长,所以我把它包含在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 2012-03-07 00:13:36

+0

以何种方式是不正确的? – giodamelio 2012-03-07 00:15:44

+2

那么,insulated_copper_cable不是一个基础项目,是吗? electronic_circuit也不是。看来你想要的基础成分,而不是复杂的。 – PearsonArtPhoto 2012-03-07 00:20:09

回答

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

他希望的输出是一个字典,所以,而不是chain.append,你应该做* chain.setdefault(item,0)+ = quantity * – 2012-03-07 00:23:36

+0

@campos:这不会按预期工作,值不会增加。 'defaultdict(int)'在这里是理想的数据结构。 – 2012-03-07 00:24:19

+0

哎呀,这是真的。 – 2012-03-07 00:27:13