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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

Q&A

解決済

2回答

500閲覧

pythonでjsonと書き込み

kohekoh

総合スコア140

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

0グッド

0クリップ

投稿2017/06/30 05:12

編集2017/06/30 05:19

以下のようなコードがあります

python

1import json 2 3def main(): 4 5 userloc = [] 6 userloc2 = [] 7 8 f = open("tips.txt","r",encoding='utf-8_sig')#,encoding='utf-8_sig' 3系バージョン 9 for line in f: 10 json_dict = json.loads(line) 11 userloc.append([json_dict["user_id"],json_dict["business_id"],json_dict["text"]]) 12 13 for x in userloc: 14 userloc2.append(x) 15 userloc2.append("\n") 16 17 userloc_str = map(str,userloc2) 18 19 with open("userloc(gati).txt","w") as fw: 20 fw.writelines(userloc_str) 21 22if __name__ == "__main__": 23 main() 24 25------------------------------------------------ 26実行結果 27 28Traceback (most recent call last): 29 File "get_userloc.py", line 30, in <module> 30 main() 31 File "get_userloc.py", line 24, in main 32 fw.writelines(userloc_str) 33UnicodeEncodeError: 'cp932' codec can't encode character '\xe9' in position 137: illegal multibyte sequence 34

このような結果が帰ってきます
どうすればよいですか?

ちなみに実装環境はanacondaの4.4.0でpython3.6.1です
ちなみにwindowsです

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

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

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

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

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

guest

回答2

0

ベストアンサー

原因はlistをuserloc_str = map(str,userloc2)で文字列にしていますが、マルチバイトですと

['\x82\xc9\x82\xd9\x82\xf1\x82\xb2']

みたいな文字になってしまいます。
それをエスケープせずに書き込みしようとしているエラーです。

コードを見ましたが、質問者がやりたいことはjson.loadjson.dumpを使えば2~3行程度で済む処理です。
わざわざtxtにして煩雑な処理にしています。

おそらくやりたいことは

https://docs.python.jp/3/library/json.html

をよく読んで理解すれば、非常に簡潔に書けるはずです。


追記

ファイルが10万行という事で、巨大なファイルなのでデータをいじらないほうがいいでしょう。

書き込みの部分をuserloc_str = map(str,userloc2)で変換するのではなくjson.dumpsを使って下さい。

python

1with open("userloc(gati).txt","w") as fw: 2 for x in userloc: 3 fw.write(json.dumps(x) + "\n")

投稿2017/06/30 05:33

編集2017/06/30 07:50
pashango2

総合スコア930

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

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

kohekoh

2017/06/30 07:04

もともとのファイルが中身はjsonなのですが テキストファイルになっているので このような形でしています
pashango2

2017/06/30 07:09

でしたら、 userloc = json.load(open("tips.txt")) json.dump(userloc, open("userloc(gati).txt","w")) のように書かない理由は何ですか?
pashango2

2017/06/30 07:13

現状は上記のように書けませんよね? それは、中途半端なJSONだからです(行単位にJSONを書いている?) txt全体をJSONにすれば、すべて1行で簡潔に書けるはずですよ。
kohekoh

2017/06/30 07:19

中途半端なjsonとはどういうことでしょうか ひとまとまりにしてしまえばいいということですか? ちなみに現状は [] [] [] … このような形になっています
kohekoh

2017/06/30 07:20

また、上のコードでは "user_id"等をもってくることができないと思います
pashango2

2017/06/30 07:22

[ [], [], ... ] このような形にすればjson.loadの1行だけで読めるのではないですか? forとjson.loadsでループを回す必要はありません。
pashango2

2017/06/30 07:29 編集

私が書くのであれば質問のコード処理はこんな感じで書きます。 userloc = json.load(open("tips.txt","r",encoding='utf-8_sig')) userloc2 = [[x["user_id"], x["business_id"], x["text"]] for x in userloc] json.dump(userloc2, open("userloc(gati).txt","w"))
kohekoh

2017/06/30 07:30

たしかに… f = open("tips(exa).txt",encoding='utf-8_sig') t = [] for x in f: t.append(f) さきにこうすればよいということですかね?
pashango2

2017/06/30 07:33

いいえ、tips.txtの内容を[]で囲んだJSON形式にすれば、上のコメントのように3行で済みます。 ファイルを読んで、user_idなどのリストに変換して、ファイルに書き込む、すべての処理が3行です。
kohekoh

2017/06/30 07:37

tips.txtを[]で囲んだjson形式にするためにこうしたつもりだったのですが どうすればよいですか?
kohekoh

2017/06/30 07:38

ちなみに手書きでそれを変えるのは厳しいです 10万行ほどあるので
kohekoh

2017/06/30 07:46

import json userloc = [] f = open("tips(exa).txt",encoding='utf-8_sig') for line in f: json_dict = json.loads(line) userloc.append([json_dict["user_id"],json_dict["business_id"],json_dict["text"]]) t = str(userloc) with open("tips(exa).json","w") as fw: fw.writelines(t) こんな感じでjsonにかえてみました
pashango2

2017/06/30 07:53

t = str(userloc) with open("tips(exa).json","w") as fw: fw.writelines(t) は with open("tips(exa).json","w") as fw: fw.writelines(userloc) で良いです、strはいりません。 追記を書きました。
kohekoh

2017/06/30 08:00

strを抜くと TypeError: write() argument must be str, not list このようになります ちなみに追記のほうですが、うまく動きました ありがとうございます
kohekoh

2017/06/30 08:27

すこしちがう形式のものに 同じプログラムをつかったら json.decoder.JSONDecodeError: Extra data: line 1 column 1340 (char 1339) このようなエラーがでました どういうことでしょうか
pashango2

2017/06/30 08:30

情報が少なすぎてわかりませんね、新しい問題として投稿してください。
kohekoh

2017/06/30 08:35

投稿しました!
guest

0

ファイルの一行目に次の行を追加してください。

# coding: cp932

--以下追記

この回答、ローカルで実行した別のエラーを回避するものでした。
質問者様への回答ではないので間違いです。

投稿2017/06/30 05:22

編集2017/06/30 05:37
moonphase

総合スコア6621

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問