Python递归数据读取
如果您曾经玩过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}
所以问题是,我该怎么做呢?
我知道要求人们为你做的工作在这里皱起了眉头,所以如果你觉得这与你有点太接近,只是为我编码,就这么说吧。
这可以使用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}
我认为问题是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
他希望的输出是一个字典,所以,而不是chain.append,你应该做* chain.setdefault(item,0)+ = quantity * – 2012-03-07 00:23:36
@campos:这不会按预期工作,值不会增加。 'defaultdict(int)'在这里是理想的数据结构。 – 2012-03-07 00:24:19
哎呀,这是真的。 – 2012-03-07 00:27:13
只是说,但我觉得你的样本输出是不正确的...... – PearsonArtPhoto 2012-03-07 00:13:36
以何种方式是不正确的? – giodamelio 2012-03-07 00:15:44
那么,insulated_copper_cable不是一个基础项目,是吗? electronic_circuit也不是。看来你想要的基础成分,而不是复杂的。 – PearsonArtPhoto 2012-03-07 00:20:09