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

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

ただいまの
回答率

90.34%

  • Python

    9190questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7397questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Pythonにおけるタプルとリストの扱われ方について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 195

harunouta

score 100

 前提・実現したいこと

月ごとと年ごとの果物の収穫高を比較するプログラムを書いています。
比較した結果を反映した文章に起こしたいです。
上昇が見られたものとそうでないもの(下降傾向)をまとめようとしています。

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

コード1の実行結果では、タプル型ではpopができないとのエラーがでており、

Traceback (most recent call last):
  File "untitled.py", line 61, in <module>
    month_index = month_data.pop(-1)
AttributeError: 'tuple' object has no attribute 'pop'

 該当のソースコード

コード1

fruits = [ #foodptice category
    "かき",
    "りんご",
    "みかん"
]

index = {
    "2017": {
        "1月": [901, 997, 1003],
        "2月": [918, 984, 1005],
        "3月": [891, 985, 1007]
    },
    "2018": {
        "1月": [885, 1006, 1010],
        "2月": [877, 975, 1006],
        "3月": [928, 999, 1006]
    }
}

def month_change(m1, m2, m3):

    month_status = [0]*len(fruits)
    for idx_cat,cat in enumerate(fruits): 
        print(idx_cat,cat)
        month_status[idx_cat] = (cat, 100*(m2[idx_cat] - m1[idx_cat])/m1[idx_cat],
                100*(m3[idx_cat] - m2[idx_cat])/m2[idx_cat])

    return tuple(month_status)

month_data = month_change(index['2018']['1月'], 
        index['2018']['2月'],
        index['2018']['3月'])

#for a single tuple
res1 = ()
for rows in month_data:
    res1 = res1 + rows

def year_change(y1, y2):
    months = ['1月', '2月', '3月']
    year_status = [0]*len(fruits)
    for idx_cat,cat in enumerate(fruits):
        year_furuits = [cat] + [0]*len(months)
        for idx_month,month in enumerate(months):
            print(idx_cat, cat, idx_month, month)
            year_furuits[idx_month+1] = 100*(y2[month][idx_cat]
                    - y1[month][idx_cat])/y1[month][idx_cat]

        year_status[idx_cat] = tuple(year_furuits)

    return tuple(year_status)

year_data = year_change(index['2017'],index['2018'])

#for a single tuple
res2 = ()
for rows in year_data:
    res2 = res2 + rows


month_index = month_data.pop(-1)
year_index = year_data.pop(-1)

def sentence(idx_data, factor_data):
    if idx_data[-1] > 0:
        contributor = []
        discounter = []
        for factor in factor_data:
            if factor[-1] > 0:
                contributor.append(factor)
            else:
                discounter.append(factor)

        contributor.sort(key=lambda data:data[-1]-data[-2], reverse=True)
        discounter.sort(key=lambda data:data[-1]-data[-2])
        contributor_fragments = []

        contributor_fragments = []
        for idx, contrib in enumerate(contributor):
            prev_time = ''
            if idx == 0:
                prev_time = "2月に"
            sentence = "{} ({:.1f} % から {:.1f} %{})".format(contrib[0].lower(), contrib[-1], contrib[-2], prev_time)
            contributor_fragments.append(sentence)

        print(contributor_fragments)
        contributor_sentence = '; '.join(contributor_fragments[:-1]) + 'と' + contributor_fragments[-1] + '.'

        discounter_fragments = []
        # the completion is left as an exercise
        for idx, contrib in enumerate(contributers):
            prev_time = "%)"
            senetence 

        sentence1 = "上昇が見られたのは、" + contributor_sentence
        if len(discounter_fragments):
            sentence1 = sentence1 + "一方、" + discounter_sentence
        return sentence1
    else:
        # idx_data[-1] <= 0 に関して明記しなくてはならないか
        return ''

sentence1 = sentence(year_index, year_data)

試したこと

タプル型ではなく、リスト型に変更し、「sentence1」を出力したところ、

>>> sentence1
''


と出力され、文章の出力には至りませんでした。

コード2

fruits = [ #foodptice category
    "かき",
    "りんご",
    "みかん"
]

index = {
    "2017": {
        "1月": [901, 997, 1003],
        "2月": [918, 984, 1005],
        "3月": [891, 985, 1007]
    },
    "2018": {
        "1月": [885, 1006, 1010],
        "2月": [877, 975, 1006],
        "3月": [928, 999, 1006]
    }
}

def month_change(m1, m2, m3):

    month_status = [0]*len(fruits)
    for idx_cat,cat in enumerate(fruits): 
        print(idx_cat,cat)
        month_status[idx_cat] = (cat, 100*(m2[idx_cat] - m1[idx_cat])/m1[idx_cat],
                100*(m3[idx_cat] - m2[idx_cat])/m2[idx_cat])

    return month_status

month_data = month_change(index['2018']['1月'], 
        index['2018']['2月'],
        index['2018']['3月'])

def year_change(y1, y2):
    months = ['1月', '2月', '3月']
    year_status = [0]*len(fruits)
    for idx_cat,cat in enumerate(fruits):
        year_furuits = [cat] + [0]*len(months)
        for idx_month,month in enumerate(months):
            print(idx_cat, cat, idx_month, month)
            year_furuits[idx_month+1] = 100*(y2[month][idx_cat]
                    - y1[month][idx_cat])/y1[month][idx_cat]

        year_status[idx_cat] = tuple(year_furuits)

    return year_status

year_data = year_change(index['2017'],index['2018'])


month_index = month_data.pop(-1)
year_index = year_data.pop(-1)

def sentence(idx_data, factor_data):
    if idx_data[-1] > 0:
        contributor = []
        discounter = []
        for factor in factor_data:
            if factor[-1] > 0:
                contributor.append(factor)
            else:
                discounter.append(factor)

        contributor.sort(key=lambda data:data[-1]-data[-2], reverse=True)
        discounter.sort(key=lambda data:data[-1]-data[-2])
        contributor_fragments = []

        contributor_fragments = []
        for idx, contrib in enumerate(contributor):
            prev_time = ''
            if idx == 0:
                prev_time = "2月に"
            sentence = "{} ({:.1f} % から {:.1f} %{})".format(contrib[0].lower(), contrib[-1], contrib[-2], prev_time)
            contributor_fragments.append(sentence)

        print(contributor_fragments)
        contributor_sentence = '; '.join(contributor_fragments[:-1]) + 'と' + contributor_fragments[-1] + '.'

        discounter_fragments = []
        # the completion is left as an exercise
        for idx, contrib in enumerate(contributers):
            prev_time = "%)"
            senetence 

        sentence1 = "上昇が見られたのは、" + contributor_sentence
        if len(discounter_fragments):
            sentence1 = sentence1 + "一方、" + discounter_sentence
        return sentence1
    else:
        # idx_data[-1] <= 0 について何か明記しなくてはならない?
        return ''

sentence1 = sentence(year_index, year_data)

 補足情報(FW/ツールのバージョンなど)

Python 3.6.3

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • umyu

    2018/04/21 13:14

    質問文の本文が記載されていないみたいです、質問文を変更して本文に内容を記載指定頂いてもよろしいでしょうか?

    キャンセル

  • harunouta

    2018/04/21 13:18

    ご迷惑をおかけして申し訳ございません。

    キャンセル

  • umyu

    2018/04/21 13:21

    >harunoutaさんへ 質問の編集ありがとうございます。質問のコードは作成中のコードではなく、単純化したコードを乗せる事をお勧め致します。

    キャンセル

回答 1

checkベストアンサー

+2

return ''の方の分岐に入ったのでは?


tupleはimmutableなので、popはできません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/23 09:05

    ご回答いただきましてありがとうございます。
    問題なのは、文章を返す「return sentence1」の方の分岐になぜ入らないのかわからないことです。

    キャンセル

  • 2018/04/23 10:08

    idx_data[-1] > 0が満たされていないからです。
    コード全部見てデバッグすることも可能ですが、idx_dataを書き出して確認するのが一番はやいです。

    キャンセル

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

  • Python

    9190questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7397questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。