2013-10-30 41 views
6

我創建了各種各樣的食譜選擇,我期待建立一個統一的字典模板。目前,我有這樣的事情:是否有可能創建一個字典「模板」?

menu_item_var = {'name': "Menu Item", 'ing': (ingredients)} 

我很擔心重新輸入nameing爲每menu_item_var,時間的緣故而誤鍵的可能的災難。我知道我可以在我的tuple,中添加Menu Item作爲項目0,刪除dict並運行for循環以使詞典更安全,但不會將原始menu_item_vartuple轉換爲dict。有沒有一個「更聰明」的方式來做到這一點?

+0

怎麼樣簡單地做{「MENU_ITEM」:「成分」,...},而不是有「名'和'ing'作爲額外的處理步驟。會讓你的邏輯變得簡單一些。 –

+3

['collections.namedtuple'](http://docs.python.org/2/library/collections.html#collections.namedtuple)? – BrenBarn

+0

甚至只是一個元組?成對的名稱和值非常普遍。 – Eevee

回答

5

我可能會建議在尋找創建一個類,並使用OOP,而不是這樣的事情。

class Recipe: 
    def __init__(self,name,ingredients): 
     self.name = name 
     self.ingredients = ingredients 
    def __str__(self): 
     return "{name}: {ingredients}".format(name=self.name,ingredients=self.ingredients) 

toast = Recipe("toast",("bread")) 
sandwich = Recipe("sandwich",("bread","butter","ham","cheese","butter","bread")) 

隨着「模板」變得越來越複雜,它不僅僅是一個數據定義,而且需要邏輯。使用一個類將允許你封裝這個。

例如,我們的夾心以上有2個麪包和2塊黃油。我們可能要跟蹤這個內部,就像這樣:

class Recipe: 
    def __init__(self,name,ingredients): 
     self.name = name 
     self.ingredients = {} 
     for i in ingredients: 
      self.addIngredient(i) 
    def addIngredient(self, ingredient): 
     count = self.ingredients.get(ingredient,0) 
     self.ingredients[ingredient] = count + 1 
    def __str__(self): 
     out = "{name}: \n".format(name=self.name) 
     for ingredient in self.ingredients.keys(): 
      count = self.ingredients[ingredient] 
      out += "\t{c} x {i}\n".format(c=count,i=ingredient) 
     return out 

sandwich = Recipe("sandwich",("bread","butter","ham","cheese","butter","bread")) 
print str(sandwich) 

這給了我們:

sandwich: 
    2 x butter 
    1 x cheese 
    1 x ham 
    2 x bread 
1

有幾個非常簡單的這樣做的方法。我能想到的最簡單的方法就是創建一個函數來返回字典對象。

def get_menu_item(item, ingredients): 
    return {'name': item, 'ing': ingredients} 

只是把它像這樣...

menu_item_var = get_menu_item("Menu Item", (ingredients)) 

編輯:編輯使用一致的代碼風格,每PEP8。

+0

最好與命名一致(camelCase/under_score)。 PEP8建議使用小寫字母+下劃線。在附註中,歡迎來到SO。 :) – dparpyani

+0

大聲笑,謝謝。我通常使用camelCase來處理所有事情(因爲我做了很多Java開發),但也複製/粘貼了他的變量。但適當注意。 – therearetwoosingoose

1

或者什麼therearetwoosingoose建議,

>>> menu_item = lambda name, ing: {'name': name, 'ing': ing} 
>>> sandwich = menu_item('sandwich', ['cheese', 'tomato']) 

現在三明治:

>>> sandwich 
{'name': 'sandwich', 'ing': ['cheese', 'tomato']} 
+0

這個解決方案的確很簡單直接。我只是用它來做類似的事情,它的工作原理! – RodrikTheReader

2

字典是鍵值映射關係,一般用於有一個靈活的結構。類實例是帶着一幫性質的,一般使用時,你有一個數字,都有着類似的結構對象的對象。

您的「字典模板」聽起來更像是一個類(並且需要適合這個單一模板的所有字典都將是該類的實例),因爲您希望這些字典不是未知組的集合 - 值對,但在已知名稱下包含特定標準的一組值。

collections.namedtuple是構建和使用正是這種類的(一個其實例只是一組特定的領域對象)的一個極其輕量級的方式。例如:

>>> from collections import namedtuple 
>>> MenuItem = namedtuple('MenuItem', ['name', 'ing']) 
>>> thing = MenuItem("Pesto", ["Basil", "Olive oil", "Pine nuts", "Garlic"]) 
>>> print thing 
MenuItem(name='Pesto', ing=['Basil', 'Olive oil', 'Pine nuts', 'Garlic']) 
>>> thing.name 
'Pesto' 
>>> thing.ing 
['Basil', 'Olive oil', 'Pine nuts', 'Garlic'] 

「缺點」是它們仍然是元組,並且是不可變的。根據我的經驗,對於簡單的簡單數據對象通常是一件好事,但這可能是您考慮的用法的一個缺點。

+0

其實我唯一可以想象的問題是,每種成分都是3的元組,一個成分名稱,一個由客人數量和單位改變的等式。我最初將這些元組作爲列表,以便當客人數改變時等式會發生變化,但據我所知我必須在要更改列表之前建立客人數或以某種方式回憶變量。 –

1

你可以嘗試使用JSON和字符串插值來創建一個非常基本的字典模板:

import json 
template = '{"name": "Menu Item", "ing": %s }' 

def render(value): 
    return json.loads(template % json.dumps(value)) 

render([1,2,3]) 
>> {u'ing': [1, 2, 3], u'name': u'Menu Item'} 
相關問題