質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

classで作成したインスタンスをfor文で回す方法が知りたい。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 113

atk_721

score 28

前提・実現したいこと

インスタンスをリストのように格納する関数を作成したいのですが、どのようなコードを書けばいいのでしょうか?

発生している問題・エラーメッセージ

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-223-7a22154e3b02> in <module>
     20 
     21 for i in range(1,5):
---> 22     print('商品名:{0}, 価格 :{1},カロリー:{2}'.format(cake[i].name,cake[i].price,cake[i].calorie))

TypeError: 'Menu' object is not subscriptable

該当のソースコード

class Menu:

    def __init__(self,name,price,calorie):
        self.name = name 
        self.price = price
        self.calorie = calorie

    def info(self):
        return 'name : {} , price : {} , calorie : {}'.format(self.name,self.price,self.calorie)

drink1 = Menu('cola',120,50)
drink2 = Menu('tea',60,20)
drink3 = Menu('mineral water',100,10)
drink4 = Menu('ryokucha',120,20)

cake1 = Menu('monbrancake',500,600)
cake2 = Menu('shortcake',600,300)
cake3 = Menu('cheesecake',800,700)
cake4 = Menu('macchacake',400,500)

for i in range(1,5):
    print('商品名:{0}, 価格 :{1},カロリー:{2}'.format(cake[i].name,cake[i].price,cake[i].calorie))

試したこと

cake_list.append(cake1)
cake_list.append(cake2)
for i in range(1,3):
    print(cake_list[i].name)

#monbrancake
 shortcake


このようにすると取り出せるのですが、
cake1のすべてのname,price,calorieを
同時に取り出したいです。
もっとスマートな書き方が知りたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • quiqui

    2019/08/14 20:56

    > cake1のすべてのname,price,calorieを
    とありますがcake1はひとつずつのname,price,calorieしか持っていないので誤記か、不足があると思います。

    発生している問題・エラーメッセージと該当のソースコードが合っていないようにも見えます(ソースコードにcakeがない)。

    質問は修正可能ですので直すとよいでしょう。

    キャンセル

回答 4

+2

インスタンスをリストのように格納する

そのままリストを使えば良いのでは。

cakes = [
    Menu('monbrancake', 500, 600),
    Menu('shortcake', 600, 300),
    Menu('cheesecake', 800, 700),
    Menu('macchacake', 400, 500),
]

for cake in cakes:
    print('商品名:{0}, 価格 :{1},カロリー:{2}'.format(cake.name, cake.price, cake.calorie))

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/14 21:01

    素早い回答ありがとうございました。納得出来ました。

    キャンセル

+2

from collections import namedtuple

class Menu(namedtuple("_Menu", "name price calorie")):
    def info(self):
        return 'name : {} , price : {} , calorie : {}'.format(*self)

drink = [Menu('cola', 120, 50),
         Menu('tea', 60, 20),
         Menu('mineral water', 100, 10),
         Menu('ryokucha', 120, 20)]

cake = [Menu('monbrancake', 500, 600),
        Menu('shortcake', 600, 300),
        Menu('cheesecake', 800, 700),
        Menu('macchacake', 400, 500)]

for name, price, calorie in cake:
    print('商品名:{0}, 価格 :{1},カロリー:{2}'.format(name, price, calorie))

もしくは

for item in cake:
    print('商品名:{0}, 価格 :{1},カロリー:{2}'.format(*item))

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/15 15:55

    回答ありがとうございます。
    後者の書き方なのですが、.format(*item)の所の処理がどうなっているのか分からないのですがソースなどは無いでしょうか?個人的にとてもスッキリしていて良いなと思いました。

    キャンセル

  • 2019/08/15 16:05

    「.format(*item)」は「.format(item[0], item[1], item[2], ...)」というふうに引数を展開するときの書き方です。この例では、itemはnamedtupleを元に定義されているので、item[0]とitem.name、item[1]とitem.price、item[2]とitem.calorieが対応するので、最終的に「.format(*item)」と「.format(item.name, item.price, item.calorie)」が同義になるという仕掛けです。

    キャンセル

  • 2019/08/15 16:22

    回答ありがとうございます!まさに探していた物でした。とても勉強になりました。

    キャンセル

+1

次のコードを研究してみてください。
x.py

class Menu:
    def __init__(self, name, price, calorie):
        self.name = name 
        self.price = price
        self.calorie = calorie

    def __str__(self):
        return '商品名: {}, 価格: {}, カロリー: {}'.format(self.name, self.price, self.calorie)

    def attributes(self):
        return {'商品名': self.name, '価格': self.price, 'カロリー': self.calorie}

cake1 = Menu('monbrancake',    500, 600)
cake2 = Menu('shortcake',      600, 300)
cake3 = Menu('cheesecake',     800, 700)
cake4 = Menu('macchacake',     400, 500)

cakes = [cake1, cake2, cake3, cake4]
for cake in cakes:
    print(cake)

print()
drinks = [
    Menu('cola',          120, 50),
    Menu('tea',            60, 20),
    Menu('mineral water', 100, 10),
    Menu('ryokucha',      120, 20)
]
[print(drink) for drink in drinks]

print()
orders = []
orders.append(cakes[0])
orders.append(drinks[1])
orders.append(drinks[2])

print("ご注文")
[print("{:10}: {}".format(x.price, x.name)) for x in orders]
print("合計:", sum([x.price for x in orders]))

実行例
イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/17 17:14

    回答ありがとうございます。勉強になります。動かしてみたのですが処理の流れがいまいち掴めません、、、インスタンスを作成すると同時に__str__がreturnで出力しているのだと思うのですが、__Attributes__も呼び出されているはずなのに、、、よろしければこの書き方が説明されているソースのようなものがあれば紹介していただきたいです。

    キャンセル

  • 2019/08/17 17:17

    [print("{:10}: {}".format(x.price, x.name)) for x in orders]
    この書き方は大変勉強になりました。

    キャンセル

  • 2019/08/17 23:44

    attributes() メソッドは使われていません。(削除しても動作します)

    参考情報
    - https://www.python.ambitious-engineer.com/archives/338
    基本的な特殊メソッドと__str__

    - https://qiita.com/jeyei/items/7617499e6f0c9544a0a4
    Python内包表記をprintする際のお作法

    キャンセル

  • 2019/08/18 03:31

    詳しいソースありがとうございます。助かりました。

    キャンセル

checkベストアンサー

0

例えば、こういう書き方を思いつきます。

class Menu:
    def __init__(self, name, price, calorie):
        self.name = name
        self.price = price
        self.calorie = calorie

    def info(self):
        return '商品名:{0}, 価格 :{1}, カロリー:{2}'.format(self.name, self.price, self.calorie)


cake_list = [
    Menu('monbrancake', 500, 600),
    Menu('shortcake', 600, 300),
    Menu('cheesecake', 800, 700),
    Menu('macchacake', 400, 500),
]

for cake_menu in cake_list:
    print(cake_menu.info())


商品名:monbrancake, 価格 :500, カロリー:600
商品名:shortcake, 価格 :600, カロリー:300
商品名:cheesecake, 価格 :800, カロリー:700
商品名:macchacake, 価格 :400, カロリー:500

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/14 21:00

    すぐに回答していただきありがとうございました。
    分かり易かったです。自分には思いつきませんでした、、、、

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る