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

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

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

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

Q&A

1回答

275閲覧

python ランキング 書き込み

aaa12

総合スコア18

Python

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

0グッド

1クリップ

投稿2017/10/13 15:29

編集2017/10/16 05:29

以前作っていただいたコードを書き直してランク付けした上で他のtxtファイルに移す作業のコードを教えていただきたいです。

https://teratail.com/questions/96246
前回質問し、教えていただいた内容です。コードも教えていただきました。

python

1with open('file1.txt') as f: 2 value_list = [line.rstrip() for line in f] 3 4with open('file2.txt') as f: 5 key_list = [line.rstrip() for line in f] 6data_dict = {} 7for raw_value in value_list: 8 key, value = raw_value.split(';') 9 if key in data_dict: 10 data_dict[key].append(value) 11 else: 12 data_dict[key] = [value] 13 14for key, values in sorted(data_dict.items(), key=lambda x: -len(x[1])): 15 for value in values: 16 print(key + ';' + value) 17 18 if len(values) == 0: 19 pass 20 else: 21 print(len(values))

以上です。表記の仕方がわかりにくかったらおっしゃってください。
今、ファイル1にはソートされた下記のようなデータが100万近くあります。
1234567;7890984
1234567;8764589
1234567;9275785
1345678;9868465
2345678;8979894
2345678;9078990
またファイル2にはソートされた下記のようなデータが30万近くあります。
1234567
1345678
2347889

結果としては、
ファイル1の;より左の数値とファイル2が合致した時のみを考え、合致した場合はファイル1にその数字を含む行がいくつあるのかを数え上位からランク付けします。
例としては、以下のようです。
1234567;7890984
1234567;8764589
1234567;9275785
3
1345678;9868465
1

このように解決、編集していただきました。そのコードに手を加えさせていただき、新しくコードを書きました。(このコードの結果を別のファイルへ保存する方法しようと思い書きました。)
新しく、ファイルを作りそこに上記の結果を保存したいです。
下記のようなコードを書きましたが、最後のf3.write(str1)のところで通りません。(f3.writeは2回しようしてはいけないなどの決まりがありますか?)初心者なので、ヘンテコな編集になっているかもしれません。ご指摘よろしくお願いします。

python

1with open('ファイル1.txt') as f: 2 value_list = [line.rstrip() for line in f] 3 4with open('ファイル2.txt') as f: 5 key_list = [line.rstrip() for line in f] 6 7f3 = open('ファイル3.txt', 'w') 8 9data_dict = {} 10for raw_value in value_list: 11 key, value = raw_value.split(';') 12 if key in data_dict: 13 data_dict[key].append(value) 14 else: 15 data_dict[key] = [value] 16 17for key, values in sorted(data_dict.items(), key=lambda x: -len(x[1])): 18 for value in values: 19 print(key + ';' + value) 20 f3.write(key + ';' + value + '\n') 21 22 if len(values) == 0: 23 pass 24 else: 25 print(len(values)) 26 str1 = len(values) 27 f3.write(str1) 28f.close() 29

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

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

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

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

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

guest

回答1

0

Python

1# 実際にはファイルから読み込む 2value_list = ['1234567;7890984', '1234567;8764589', '1234567;9275785', '1345678;9868465', '2345678;8979894', '2345678;9078990'] 3key_list = ['1234567', '1345678', '2347889'] 4 5data_dict = {} 6for raw_value in value_list: 7 key, value = raw_value.split(';') 8 if key in data_dict: 9 data_dict[key].append(value) 10 else: 11 data_dict[key] = [value] 12 13for key, values in sorted(data_dict.items(), key=lambda x: -len(x[1])): 14 # for value in values: 15 # print(key + ';' + value) 16 17 if len(values) == 0: 18 pass 19 else: 20 print(key + ';' + values[0]) 21 print(len(values)) 22 23"""実行結果(修正前) 241234567;7890984 251234567;8764589 261234567;9275785 273 282345678;8979894 292345678;9078990 302 311345678;9868465 321 33""" 34 35"""実行結果(修正後) 361234567;7890984 373 382345678;8979894 392 401345678;9868465 411 42"""

前回書いたのは書き捨てのプログラムだったため、変更が必要でした。
どんどん仕様が増えていくと、コーディングの見通しが立ちません。
出来るだけ序盤に『何が出来る必要があるのか』を明確にするようにしてください。

下記のようなデータが100万近くあります。

このスクリプトがエラーなく動けばいいですが、ちょっと自信がないです。
大きなデータに対応させるためには、工夫が必要かもしれません。

その要素の最初の一つとそれについての要素数を書き出したいです。

修正しました。


また、別に著作権云々大騒ぎする気はありませんが...
質問で他人が書いたプログラムを引用する場合、それを明示した方がよいです。
前回質問へのリンクを貼り、更に引用符を付けるとよいでしょう。

**リンクの貼り方** [リンク先の呼称](URL) **引用符の付け方** > 引用したい文 > 引用したい文

リンクを貼ると、このようになります。

引用符をつけると、このようになります。

Python

1コードも引用できます。

追記を受けて

最後のf3.write(str1)のところで通りません。
TypeError: expected a character buffer object

エラーが再現出来ていないのですが、おそらく数値を渡しているのが原因です。
文字列にキャストしてあげてください。

Python

1str1 = len(values) 2f3.write(str(str1))

ついでに、最後closeするものを間違えています。

Python

1f.close()

明示的に閉じる必要があるのはfではなくf3では。

さらに、コメントを受けて

1回目は (中略) TypeError:cannot concatenate 'str' and 'int' objects

エラーメッセージこそ異なりますが、こういうことです。

Python

1>>> 'hoge' + 1 2Traceback (most recent call last): 3 File "<stdin>", line 1, in <module> 4TypeError: must be str, not int 5>>> 'hoge' + str(1) 6'hoge1'

あとは、質問者様ご自身がどのような工夫をしたのか見えるといいですね。
今の状態では、ただ投げ出しているのか、壁にぶつかっているのかわからないです。
人の書いたコードはよく読んで内容を把握し、そしてアレンジする技術を持ちましょう。

投稿2017/10/13 16:21

編集2017/10/16 07:35
LouiS0616

総合スコア35660

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

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

aaa12

2017/10/14 02:49 編集

ありがとうございます。様々なご指摘本当に助かります。pythonに関して、まだ始めたばかりで何も分かっておらずこの問題に対してはネットで調べ調べコードを書いたので、実行まで行っても絶対変なコードになっているので載せるのが恥ずかしいと思い載せずに質問してしまいました。次回以降載せていこうと思うので、間違っているところはすべてご指摘のほどよろしくお願いします。また。コードを勝手に乗せるような行為をしてしまい申し訳ありません。考えが足りず申し訳なかったです、、以後、気をつけていきます。 本題のコードの方ですが、無事実行することができました。コードの意味も調べ調べですが理解できました(自分で作れと言われれば100パーセント思いつきませんが、、)ありがとうございます。 また、以前読み取るデータが多い時は分割するのが良いと教えていただきやっていたのですがそれでも量が多くsshが切れてしまうことが多かったのですがscreenコマンドを使えば、切れても実行ができることがわかりました。これでやっていこうと思います。 読みやすい文章、pythonのコードの理解頑張ってやっていこうと思います。ありがとうございました!
LouiS0616

2017/10/14 04:41

ちょっと説教臭い回答になってしまいましたが、しっかりと受け止めていただけたようで良かったです。 コーディングスキルはかけた時間にある程度比例して向上します。 特に慣れないうちは成長が早いです、コーディング自体を楽しむのが成長のコツです。 頑張ってくださいね。
aaa12

2017/10/16 04:18

こんにちは。この内容をファイルに書き込むコードを書いたのですが、結局一つも実行できず進めなくなってしまいました。また、お伺いしてもよろしいですか?
LouiS0616

2017/10/16 04:26

もうちょっと具体的に言ってもらわないとわからないです。 どのようなコードを書いたのか/実行できないとは具体的になんでか
aaa12

2017/10/16 04:31

あ、はい!今から書きます。このコメント欄に書いて大丈夫ですか?
LouiS0616

2017/10/16 04:56

質問を編集する形がいいと思います。他の方も見られるかもしれません。 その際ついでに、元の質問も大枠を残したままちょっと整理してみてください。 ただ、内容を大幅に修正する必要がある場合は、新しい質問を立てるのがよいかと思います。
aaa12

2017/10/16 05:17

ありがとうございます、質問いたしました、引用の仕方はこれで大丈夫でしたか?コードが引用できず、このように書かせていただきました。また、ご指摘のほどよろしくお願いします。
LouiS0616

2017/10/16 05:28 編集

コードの引用の仕方 > ```Python > コード内容 > コード内容 > つづく > ``` 『>』も『`』も半角にすることをお忘れなく。
LouiS0616

2017/10/16 05:28

> 最後のf3.write(str1)のところで通りません。 通らないとは、具体的にどういうことでしょうか? なにかエラーメッセージは出ますか?
aaa12

2017/10/16 05:31

コードの、、、に意味があったのですね。気づかなかったです。直しました! エラーメッセージ : 1419789980;994550017 1419789980;1161721062 1419789980;833573947 1419789980;541614535 1419789980;1095105396 1419789980;1027834038 1419789980;909195402 40571 Traceback (most recent call last): File "ranking.py", line 29, in <module> f3.write(str1) TypeError: expected a character buffer object 途中までは実行されますがこのように出て止まってしまいます
LouiS0616

2017/10/16 05:46

なお、読点『、』とシングルクォート『'』、バッククオート『`』は全て別物です。 入力方法に関して、最近こんな質問がありました。 https://teratail.com/questions/96312
aaa12

2017/10/16 05:58

ありがとうございます!私もわかっていなかったです。参考になりました。
aaa12

2017/10/16 06:08

回答ありがとうございます!無事、実行できました。最後のはf3ですね。気づきませんでした。ありがとうございます。すみません、また疑問が湧いたのですが以下のように: 1419789980;994550017 1419789980;1161721062 1419789980;833573947 1419789980;541614535 1419789980;1095105396 1419789980;1027834038 1419789980;909195402 40571 1419789980が大量にあるときその出力を最初の1行にのみで終わらせる(この場合だと1419789980;994550017)場合は、print(key)のところを工夫すれば良いですか?それともfor文から出しますか? 質問ばかりで申しわけありません。 また、わかりにくくなってしまい申しわけありません。
aaa12

2017/10/16 06:08

教えていただけたら、それをヒントに自分でやってみたいです。
LouiS0616

2017/10/16 06:11

len(values)を出力する際に、一緒にkeyも出力すればよいかと思います。 逆に、print(key + ';' + value)は消さねばなりませんが。 そうすれば、以下のような結果になるはずです。 1419789980 40571
aaa12

2017/10/16 06:19

ありがとうございます! 同じように先ほどやってみたのですが 2248680602;418628087 3 2239362294;2699918654 3 2239362294;1966730466 3 2239362294;2242525488 2 2225050634;3101168706 2 2225050634;2784417402 それだとこのようになってしまって、ランキングが行間に出てきてしまうだけになってしまいます。 質問がわかりにくいようでしたら申し訳ないです。 もう一度説明します! 1419789980;994550017 1419789980;1161721062 1419789980;833573947 1419789980;541614535 1419789980;1095105396 1419789980;1027834038 1419789980;909195402 7 の時は、 1419789980;994550017 7 もしくは 1419789980 7 のようにしたいです!
LouiS0616

2017/10/16 06:21

どのようなコードで試しましたか?
aaa12

2017/10/16 06:27

1回目は print(key + ';' + value + len(values) + '\n') str1 = len(values) f3.write(key + ';' + value + str(str1) + '\n') これだと File "ranking.py", line 25, in <module> print(key + ';' + value + len(values) + '\n') TypeError: cannot concatenate 'str' and 'int' objectsの エラーが出てしまい、 2回目は print(key + ';' + value) print(len(values)) str1 = len(values) f3.write(key + ';' + value) f3.write(str(str1)) を試しましたが、先ほどのようになりました
LouiS0616

2017/10/16 06:38

行間に出てきているのはランキングではなく要素数では?
aaa12

2017/10/16 06:44

そうです!すみません、説明の仕方が不十分でした。 例えば、要素数が20個のものだとしたら、 その要素の最初の一つとそれについての要素数を書き出したいです。 例で示すと、 965334804;493964826 37 965334804;624770196 37 965334804;337137982 37 965334804;226221038 37 965334804;959738173 37 965334804;534212052 37 のように本来965334804には37の要素がありますが、出力するときにはそれを先頭の行+要素数 (965334804;493964826 37)   にしたいです 質問の仕方が下手でもうしわけないです。よろしくお願いします
aaa12

2017/10/16 06:45

つまり、 965334804;493964826 37 965334804;624770196 37 965334804;337137982 37 965334804;226221038 37 965334804;959738173 37 965334804;534212052 37 のものには 965334804;493964826 37 だけかいて、他の要素は書かないで次に行くということです
aaa12

2017/10/16 07:22

回答の編集ありがとうございます。 すみません、回答の編集のコードの意味があまり理解できませんでした。 コード自体は変える必要はないということですか?
LouiS0616

2017/10/16 07:26

コード、変更していますよ。 ついでに見づらい部分を修正しました。
aaa12

2017/10/16 07:33

コード見ていなかったです。ありがとうございます。実行できました! for文から抜け出して書いたからこのように出力出来た、という解釈であってますか?
LouiS0616

2017/10/16 07:36

for value in values:のブロックはlen(values)回だけ繰り返しますからね。
aaa12

2017/10/16 07:39

なるほど。ありがとうございます! 助かりました。もう一度このコードを1行ずつ理解しながら書き写して実行してみようと思います。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問