我正在创建各种食谱选择器,我正在寻找创建一个统一的字典模板。我现在有这样的事情:
menu_item_var = {'name': "Menu Item", 'ing': (ingredients)}
我担心每个name
重新输入ing
和menu_item_var
,这是为了时间和错误的可能灾难。我知道我可以在我的Menu Item
中添加tuple,
作为第0项删除dict
并运行for
循环以使字典更安全,但这不会转换原始字典从menu_item_var
到tuple
的{{1}}。这样做有“聪明”的方法吗?
答案 0 :(得分: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 :(得分:3)
有几种非常简单的方法可以做到这一点。我能想到的最简单的方法是创建一个函数来返回该字典对象。
def get_menu_item(item, ingredients):
return {'name': item, 'ing': ingredients}
就这样称呼它......
menu_item_var = get_menu_item("Menu Item", (ingredients))
编辑:根据PEP8编辑使用一致的代码样式。
答案 2 :(得分: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']
"缺点"是他们仍然是元组,因此是不可改变的。根据我的经验,这对于小型简单的普通数据对象来说通常是一件好事,但这可能是您考虑使用的一个缺点。
答案 3 :(得分:2)
您可以尝试使用json和字符串插值来创建一个非常基本的dict模板:
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'}
答案 4 :(得分:1)
替代therearetwoosingoose建议的内容,
>>> menu_item = lambda name, ing: {'name': name, 'ing': ing}
>>> sandwich = menu_item('sandwich', ['cheese', 'tomato'])
现在三明治是:
>>> sandwich
{'name': 'sandwich', 'ing': ['cheese', 'tomato']}
答案 5 :(得分:0)
一个python3不同风格的OOP供参考。 子类别dict
<property name="hbm2ddl.auto">update</property>
用法示例
class Recipe(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.update({"name": "Menu Item"})