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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

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

Q&A

解決済

2回答

189閲覧

pythonでリスト型辞書のキー判定について

sika

総合スコア52

Python 3.x

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

0グッド

1クリップ

投稿2020/01/27 06:45

Flaskにてテンプレートに出力用にSQLのクエリー結果を加工する際にユニークキーとして
日付をdictのキーとして、その他のデータをvalueにしたいのですが、
出力用のリストにキーとなる日付のdictオブジェクトがなければ の条件文
if not [d.get(key_date) for d in frames_list if key_date]:
がうまく機能しておりません

SQLクエリーのオブジェクト(date_list)

[ {'id': 100, 'date': datetime.date(2020, 1, 27), 'time': '09:00'}, {'id': 101, 'date': datetime.date(2020, 1, 27), 'time': '10:00'}, {'id': 102, 'date': datetime.date(2020, 1, 27), 'time': '14:00'}, {'id': 103, 'date': datetime.date(2020, 1, 27), 'time': '18:00'}, {'id': 104, 'date': datetime.date(2020, 1, 27), 'time': '20:00'}, {'id': 105, 'date': datetime.date(2020, 1, 28), 'time': '11:00'}, {'id': 106, 'date': datetime.date(2020, 1, 28), 'time': '15:00'}, {'id': 107, 'date': datetime.date(2020, 1, 28), 'time': '18:00'}, {'id': 108, 'date': datetime.date(2020, 1, 28), 'time': '22:00'}, {'id': 109, 'date': datetime.date(2020, 1, 29), 'time': '09:00'}, {'id': 110, 'date': datetime.date(2020, 1, 29), 'time': '16:00'}, ]

希望している出力結果

[ {'2020-01-27': [ {'id': 100, 'time': '09:00'}, {'id': 101, 'time': '10:00'}, {'id': 102, 'time': '14:00'}, {'id': 103, 'time': '18:00'}, {'id': 104, 'time': '20:00'} ]}, {'2020-01-28': [ {'id': 105, 'time': '11:00'}, {'id': 106, 'time': '15:00'}, {'id': 107, 'time': '18:00'}, {'id': 108, 'time': '22:00'} ]}, {'2020-01-29': [ {'id': 109, 'time': '09:00'}, {'id': 110, 'time': '16:00'}, ]} ]

pythonコード

python

1 # 最終出力用リスト 2 frames_list = [] 3 # クエリーレスポンスをリスト型辞書に格納 4 date_list = [dict(row) for row in frames] 5 print(date_list) # SQLクエリーレスポンス 6 7 for i,l in enumerate(date_list): 8 # キーとなる日付を設定 9 key_date = str(date_list[i]['date']) 10 11 # frames_listにkey_dateのキーとなる値が存在しなければデータ追加(※ここがうまくいってません) 12 if not [d.get(key_date) for d in frames_list if key_date]: 13 print("{}:データ追加".format(i)) 14 # 当日分のデータ格納雛形 15 days_list = [] 16 days_dict = {key_date: days_list} 17 # レコードの日付とkey_dateが一致したデータを格納して出力用リストに追加 18 for num in range(len(date_list)): 19 if key_date == str(date_list[num]['frame_date']): 20 # 日付ごとのオブジェクトフォーマット(ID, 日付, 時間) 21 data_list.append({'id': date_list[num]['id'], 'time': date_list[num]['time']}) 22 frames_list.append(days_dict) 23 print(frames_list) 24 25

実際の出力結果

[ {'2020-01-27': [ {'id': 100, 'time': '09:00'}, {'id': 101, 'time': '10:00'}, {'id': 102, 'time': '14:00'}, {'id': 103, 'time': '18:00'}, {'id': 104, 'time': '20:00'} ]} ]

1日分の格納はできたのですが、2日目以降の格納がうまくいきません。
どなたかご教示のほど、よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2020/01/27 07:09

提示されたdate_listデータ内容と、ソースコードに相違があるようです。 (データ側に'frame_date'キー名がない) 可能であればソースコードにdata_list = [{'id': 100, ~」のように直接サンプルデータを埋め込んで 第三者が単体で実行可能なコードを提示されると回答得られやすいです。
guest

回答2

0

以下のように2段階に分けて作成する手もあります。

Python

1import datetime 2import pprint 3 4date_list = [ 5 {'id': 100, 'date': datetime.date(2020, 1, 27), 'time': '09:00'}, 6 {'id': 101, 'date': datetime.date(2020, 1, 27), 'time': '10:00'}, 7 {'id': 102, 'date': datetime.date(2020, 1, 27), 'time': '14:00'}, 8 {'id': 103, 'date': datetime.date(2020, 1, 27), 'time': '18:00'}, 9 {'id': 104, 'date': datetime.date(2020, 1, 27), 'time': '20:00'}, 10 {'id': 105, 'date': datetime.date(2020, 1, 28), 'time': '11:00'}, 11 {'id': 106, 'date': datetime.date(2020, 1, 28), 'time': '15:00'}, 12 {'id': 107, 'date': datetime.date(2020, 1, 28), 'time': '18:00'}, 13 {'id': 108, 'date': datetime.date(2020, 1, 28), 'time': '22:00'}, 14 {'id': 109, 'date': datetime.date(2020, 1, 29), 'time': '09:00'}, 15 {'id': 110, 'date': datetime.date(2020, 1, 29), 'time': '16:00'}] 16 17# 日付毎にリスト作成 18frame_list = {} 19for item in date_list: 20 date = item.pop('date').strftime('%Y-%m-%d') 21 if date not in frame_list: 22 frame_list[date] = [] 23 frame_list[date].append(item) 24pprint.pprint(frame_list) 25""" 26{'2020-01-27': [{'id': 100, 'time': '09:00'}, 27 {'id': 101, 'time': '10:00'}, 28 {'id': 102, 'time': '14:00'}, 29 {'id': 103, 'time': '18:00'}, 30 {'id': 104, 'time': '20:00'}], 31 '2020-01-28': [{'id': 105, 'time': '11:00'}, 32 {'id': 106, 'time': '15:00'}, 33 {'id': 107, 'time': '18:00'}, 34 {'id': 108, 'time': '22:00'}], 35 '2020-01-29': [{'id': 109, 'time': '09:00'}, {'id': 110, 'time': '16:00'}]} 36""" 37 38# 日付の昇順に並べ替え 39frame_list = [ {k:frame_list[k]} for k in sorted(frame_list.keys())] 40pprint.pprint(frame_list) 41""" 42[{'2020-01-27': [{'id': 100, 'time': '09:00'}, 43 {'id': 101, 'time': '10:00'}, 44 {'id': 102, 'time': '14:00'}, 45 {'id': 103, 'time': '18:00'}, 46 {'id': 104, 'time': '20:00'}]}, 47 {'2020-01-28': [{'id': 105, 'time': '11:00'}, 48 {'id': 106, 'time': '15:00'}, 49 {'id': 107, 'time': '18:00'}, 50 {'id': 108, 'time': '22:00'}]}, 51 {'2020-01-29': [{'id': 109, 'time': '09:00'}, {'id': 110, 'time': '16:00'}]}] 52"""

投稿2020/01/27 08:07

can110

総合スコア38234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sika

2020/01/27 17:42

質問コードの不備申し訳ございません。 そしてご回答ありがとうございます。 コードを拝見して複雑に考えすぎていたなと反省しました。 popメソッドの使い方とソートコード参考にさせていただきます。 ありがとうございました。
guest

0

ベストアンサー

if文でkey_dateがなかったときしか処理してないのが原因です。あったときの処理も書きましょう。

all関数かany関数を使うと楽ですよ。
allなら「すべてにキーがない」、anyなら「notどれかにキーがある」=「どれにもキーがない」。
使わない方法も最後に書いておきます。

python

1import datetime 2from pprint import pprint 3 4date_list = [ 5 {'id': 100, 'date': datetime.date(2020, 1, 27), 'time': '09:00'}, 6 {'id': 101, 'date': datetime.date(2020, 1, 27), 'time': '10:00'}, 7 {'id': 102, 'date': datetime.date(2020, 1, 27), 'time': '14:00'}, 8 {'id': 103, 'date': datetime.date(2020, 1, 27), 'time': '18:00'}, 9 {'id': 104, 'date': datetime.date(2020, 1, 27), 'time': '20:00'}, 10 {'id': 105, 'date': datetime.date(2020, 1, 28), 'time': '11:00'}, 11 {'id': 106, 'date': datetime.date(2020, 1, 28), 'time': '15:00'}, 12 {'id': 107, 'date': datetime.date(2020, 1, 28), 'time': '18:00'}, 13 {'id': 108, 'date': datetime.date(2020, 1, 28), 'time': '22:00'}, 14 {'id': 109, 'date': datetime.date(2020, 1, 29), 'time': '09:00'}, 15 {'id': 110, 'date': datetime.date(2020, 1, 29), 'time': '16:00'}, 16] 17 18frames_list = [] 19for i, d in enumerate(date_list): 20 key_date = f"{d['date']:%Y-%m-%d}" 21 if all(key_date not in day_dict for day_dict in frames_list): 22 print("{}:データ追加".format(i)) 23 day_dict = {key_date: []} 24 frames_list.append(day_dict) 25 day_dict[key_date].append({'id': d['id'], 'time': d['time']}) 26pprint(frames_list)

実行結果

0:データ追加 5:データ追加 9:データ追加 [{'2020-01-27': [{'id': 100, 'time': '09:00'}, {'id': 101, 'time': '10:00'}, {'id': 102, 'time': '14:00'}, {'id': 103, 'time': '18:00'}, {'id': 104, 'time': '20:00'}]}, {'2020-01-28': [{'id': 105, 'time': '11:00'}, {'id': 106, 'time': '15:00'}, {'id': 107, 'time': '18:00'}, {'id': 108, 'time': '22:00'}]}, {'2020-01-29': [{'id': 109, 'time': '09:00'}, {'id': 110, 'time': '16:00'}]}]

all/any を使わない処理方法

python

1frames_list = [] 2for i, d in enumerate(date_list): 3 key_date = f"{d['date']:%Y-%m-%d}" 4 for day_dict in frames_list: 5 if key_date in day_dict: 6 break 7 else: 8 print("{}:データ追加".format(i)) 9 day_dict = {key_date: []} 10 frames_list.append(day_dict) 11 day_dict[key_date].append({'id': d['id'], 'time': d['time']})

投稿2020/01/27 07:25

編集2020/01/27 08:10
shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sika

2020/01/27 17:44

ご回答と詳細な解説までしていただきありがとうございます。 all関数かany関数のサンプルも含め、理想的なコード大変勉強になりました。 ベストアンサーとさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問