Рекурсивное чтение данных Python
Следующее будет иметь больше смысла, если вы когда-либо играли в майнкрафт. Поскольку многие из вас этого не сделали, я постараюсь объяснить это как можно лучше
Я пытаюсь написать рекурсивную функцию, которая может найти шаги для создания любого предмета майнкрафта из набора файлов рецептов майнкрафта. Это меня действительно поставило в тупик.
Плоский файл довольно длинный, поэтому я включил его в эту суть.
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 ответа
Это может быть элегантно решено с помощью 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
РЕДАКТИРОВАТЬ: комментарии заполняют мое отсутствие знаний Python, так что вот лучшее решение.
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