2017-11-04 5 views
1

誰でもこの機能を手伝ってくれますか?コードを書く手がかりがなく、関数本体に書いたものが間違っています。タイプdict:リストである値

def get_quantities(table_to_foods: Dict[str, List[str]]) -> Dict[str, int]: 

    """The table_to_foods dict has table names as keys (e.g., 't1', 't2', and 
    so on) and each value is a list of foods ordered for that table. 

    Return a dictionary where each key is a food from table_to_foods and each 
    value is the quantity of that food that was ordered. 

    >>> get_quantities({'t1': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'], 
    't3': ['Steak pie', 'Poutine', 'Vegetarian stew'], 't4': ['Steak pie', 'Steak pie']}) 
    {'Vegetarian stew': 3, 'Poutine': 2, 'Steak pie': 3}  
    """ 

    food_to_quantity = {} 
    for t in table_to_foods: 
     for i in table_to_foods[t]: 
      if i in table_to_foods[t]: 
       food_to_quantity[i] = food_to_quantity[i] + 1 

    return food_to_quantity 

答えて

1

使用Counters

from collections import Counter 

def get_quantities(table_to_foods: Dict[str, List[str]]) -> Dict[str, int]: 
    return dict(Counter(x for v in table_to_foods.values() for x in v)) 

あなたはおそらくからdictを加える必要はありませんCounterCounterdictのサブクラスである)が、あなたの種類が同一であるので、私はここでそれを行う

+0

ありがとうございました。これは私の最初のコンピュータサイエンスコースなので、まだカウンターメソッドを学んでいませんでした。カウンターなしで機能を解決する方法があると思いますか?また、私の教授は私にfood_to_quantityを返すことを望みます。私はあまりにも多くを尋ねるなら、すみません。 –

+1

このように 'sum'を使うと、多くの一時的な' Counter'オブジェクトが次のステップ( 'sum'特殊ケース[rejects]' str')の後にそれらを破棄して同じ非効率性を防止するだけですが、それは一般的な場合)。それをやり直してください。これは、 'dict(Counter(xはvのxのためのtable_to_foods.values()のためのxのためのカウンター)')として実行されます。 'sum'を使った時間はgenexpr入力で1つの' Counter 'を使ったときの5倍であり、入力が大きくなるにつれて悪化します)。 – ShadowRanger

+0

私はメソッド@ShadowRangerを知らないが。助けてくれてありがとう。 –

2

ライブラリなしでアイテムを数える一般的な方法は、Pythonを使用することです。get() function

foods = { 
    't1': ['banana', 'apple', 'banana'], 
    't2': ['orange', 'apple', 'banana'], 
    't3': ['apple', 'grapes', 'banana'] 
    } 

def get_quantities(foodLists): 
    totals = {} 
    for foodList in foodLists.values(): 
     for food in foodList: 
      totals[food] = totals.get(food, 0) + 1 
    return totals 

print(get_quantities(foods)) 

出力します

{'banana': 4, 'apple': 3, 'orange': 1, 'grapes': 1}

+2

'k'を使用しない場合、' items'の代わりに 'foodLists.values'ビューを使うこともできます –

+0

そのコード行には何がありますか? –

+0

@guanyuma:それは 'dict'の鍵です。あなたはそれを使用しないので、Patrickはそれを削除するように提案しました(そして、 'items'のキーと値のペアではなく' values'だけを繰り返します)。 – ShadowRanger

0

これを試してみてください:

def get_quantities(table_to_foods): 
    food_to_quantity = {} 
    for table in table_to_foods.values(): 
     for food in table: 
      food_to_quantity[food] = food_to_quantity.get(food, 0) + 1 
    return food_to_quantity 

あなたは辞書内の値を取得し、各項目を反復処理する)(.valuesを使用することができます。食べ物が辞書にある場合は、その値に1を加え、それ以外の場合は辞書に新しい項目として追加します。

辞書について
{'Poutine': 2, 'Steak pie': 3, 'Vegetarian stew': 3} 

より:itertools.chaincollections.Counterを使用してのような場合には、あなたを行うことの https://docs.python.org/3/tutorial/datastructures.html#dictionaries

+0

働いていただきありがとうございます。コードで 'もし食べ物が食べ物であるならば」。これは私が空のダイスにキーを割り当てる必要があるのですか? –

+0

'food_to_quantityの食品'は、その食品が辞書に既に入っているかどうかをチェックしていれば、その食品の現在価値に1を加算します。そうでなければ、elseステートメントは新しいキーに1の値を割り当てます。これは上記のように.get()を使用することもできます。 –

+0

私は参考にしてくれています。 –

4

ちょうど別の方法:

from itertools import chain 
from collections import Counter 

dict(Counter(chain.from_iterable(foods.values()))) 
#or Simply 
dict(Counter(chain(*foods.values()))) 

#Output: 
#{'apple': 3, 'banana': 4, 'grapes': 1, 'orange': 1} 

get_quantities({ 
    't1': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'], 
    't2': ['Steak pie', 'Poutine', 'Vegetarian stew'], 
    't3': ['Steak pie', 'Steak pie'] 
    }) 

は、出力が印刷された場合には、以下のはず

+0

これはほぼ確実に最も効率的な解決策です(特に最近のPython 3では、 'Counter 'が入力アクセラレータをカウントするのを助けるためにCアクセラレータを使用するため、' Counter' + 'Chain'を使うと入力の消費全体がCPythonのCレイヤー)。 – ShadowRanger

関連する問題