2012-03-07 51 views
5

Sau đây sẽ có ý nghĩa hơn nếu bạn đã từng chơi minecraft. Vì nhiều người trong số các bạn không có, tôi sẽ cố gắng giải thích tốt nhất là tôi có thểĐọc dữ liệu đệ quy của Python

Tôi đang cố gắng viết một hàm đệ quy có thể tìm các bước để tạo bất kỳ vật phẩm Minecraft nào từ flatfile công thức minecraft. Điều này khiến tôi thực sự bối rối.

Tệp phẳng là khá dài vì vậy tôi đã bao gồm nó trong this Gist.

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

Vì vậy, về cơ bản tôi cần phải tìm kiếm các công thức nấu ăn đầu tiên sau đó tìm kiếm các công thức nấu ăn cho tất cả các thành phần của công thức mà đầu tiên và vân vân cho đến khi bạn nhận được để các mặt hàng không có công thức nấu ăn. Mỗi lần tôi cần phải thêm các công thức vào một danh sách vì vậy tôi có được một loại tập lệnh của những gì để mục nghề trong.

Vì vậy, đây là chức năng tôi có bây giờ (một trong những không làm việc)

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 

Đây là sản lượng lý tưởng mà tôi đang sử dụng. Nó là một từ điển với tên mục và số lượng được lưu trữ trong đó.

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

Câu hỏi đặt ra là, làm cách nào để thực hiện?

Tôi biết yêu cầu mọi người làm việc cho bạn được cau mày ở đây, vì vậy nếu bạn cảm thấy điều này hơi quá gần với bạn chỉ cần viết mã cho tôi, hãy nói như vậy.

+2

Chỉ cần nói, nhưng tôi nghĩ ra mẫu của bạn là không đúng ... – PearsonArtPhoto

+0

Bằng cách nào là nó không chính xác? – giodamelio

+2

Vâng, insulated_copper_cable không phải là một mục cơ sở, phải không? Cũng không phải là electronic_circuit. Có vẻ như bạn muốn lấy các thành phần cơ bản, không phải là những nguyên liệu phức tạp. – PearsonArtPhoto

Trả lời

3

này có thể được giải quyết thanh lịch sử dụng collections.Counter, hỗ trợ bổ sung:

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

Tôi nghĩ vấn đề là 2 lần. Trước hết, bạn cần phải thêm các mục vào chuỗi trong lời gọi đệ quy đến getRecipe(). Thứ hai, tôi nghĩ rằng hai chức năng là những thứ phức tạp không cần thiết. Tôi nghĩ người bên trong nên làm. Một cái gì đó như thế này là những gì bạn đang tìm kiếm. Tôi chưa thử nghiệm nó, nhưng nó phải đủ gần để giúp bạn bắt đầu đi đúng hướng.

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 

CHỈNH SỬA: Các nhận xét đang làm thiếu kiến ​​thức về python, vì vậy đây là giải pháp tốt hơn.

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

Đầu ra mong muốn của anh ta là dict, vì vậy thay vì chain.append, bạn nên làm * chain.setdefault (mục, 0) + = quantity * –

+0

@campos: Điều này sẽ không hoạt động như mong đợi, giá trị sẽ không được tăng lên. Một 'defaultdict (int)' sẽ là cấu trúc dữ liệu lý tưởng ở đây. –

+0

oops, đó là sự thật. –

Các vấn đề liên quan