2013-10-30 24 views
6

私はレシピセレクターセレクターを作成しており、統一辞書テンプレートを作成しようとしています。私は、時間の酒と誤キーの可能性の高い災害のために、すべてのmenu_item_varためnameingを再入力が心配です辞書 "テンプレート"を作成することはできますか?

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

:私は現在、このようなものを持っています。私はtuple,の項目0としてMenu Itemを追加して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を使用して見てお勧めしたいです。

「テンプレート」がますます複雑になるにつれて、それは単なるデータ定義ではなく、ロジックを必要とします。クラスを使用すると、これをカプセル化することができます。

たとえば、私たちのサンドイッチの上には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)) 

はEDIT ...このようにそれを呼び出す:PEP8ごとに、一貫性のあるコードのスタイリングを使用する編集。

+0

命名(camelCase/under_score)と一貫している方が良いです。 PEP8は、小文字+アンダースコアを使用することを示唆しています。サイドノートでは、ようこそ。 :) – 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

あなたは試してみて、非常に基本的なdictのテンプレートを作成するには、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'} 
関連する問題