15

我正在创建各种食谱选择器,并希望创建一个统一的字典模板。我目前有这样的事情:

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

我担心重新输入,name因为时间和可能的错误密钥的灾难。我知道我可以在我的擦除中添加项目 0并运行一个循环以使字典更安全,但这不会将原件从 a转换为。有没有“更聪明”的方式来做到这一点?ingmenu_item_varMenu Itemtuple,dictformenu_item_vartupledict

4

7 回答 7

9

我可能会建议考虑创建一个类并使用 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
于 2013-10-30T04:20:29.803 回答
5

有几种非常简单的方法可以做到这一点。我能想到的最简单的方法就是创建一个函数来返回该字典对象。

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

就这样称呼吧...

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

编辑:根据 PEP8 编辑以使用一致的代码样式。

于 2013-10-30T03:45:43.113 回答
3

您可以尝试使用 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'}
于 2017-08-18T01:37:48.013 回答
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']

“缺点”是它们仍然是元组,因此是不可变的。以我的经验,这对于小型简单的纯数据对象通常是一件好事,但这可能是您想到的使用的一个缺点。

于 2013-10-30T04:58:28.167 回答
1

therearetwosingoose所建议的不同,

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

现在三明治是:

>>> sandwich
{'name': 'sandwich', 'ing': ['cheese', 'tomato']}
于 2013-10-30T04:10:53.210 回答
0

一个python3不同风格的OOP供参考。子类字典

class Recipe(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.update({"name": "Menu Item"})

示例用法

cake = Recipe(ing=('eggs', 'sugar', 'flour')
于 2019-01-15T03:29:25.377 回答
0

快速而肮脏的方式:

def menu_item(name, ing):
   return locals()

你得到:

menu_item("toast", ("bread","butter"))
>>> {'name': 'toast', 'ing': ('bread', 'butter')} 
于 2021-08-19T21:07:36.003 回答