2013-10-30 43 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'} 
相关问题