2017-01-23 11 views
1

私は.csvを読んでおり、UTF-8がコード化されています。 インデックスを作成してcsvを書き換えたいとします。 インデックスは、進行中の数字という単語の最初の文字として作成されます。 Pythonの2.7.10は、Ubuntu Serverのutf-8エンコーディング/デコードのトラブル

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
counter = 0 
tempDict = {} 
with open(modifiedFile, "wb") as newFile: 
    with open(originalFile, "r") as file: 
     for row in file: 
      myList = row.split(",") 
      toId = str(myList[0]) 

      if toId not in tempDict: 
       tempDict[toId] = counter 
       myId = str(toId[0]) + str(counter) 
       myList.append(myId) 
       counter += 1 
      else: 
       myId = str(toId[0]) + str(tempDict[toId]) 
       myList.append(myId) 

      # and then I write everything into the csv 
      for i, j in enumerate(myList): 
       if i < 6: 
        newFile.write(str(j).strip()) 
        newFile.write(",") 

       else: 
        newFile.write(str(j).strip()) 
        newFile.write("\n") 

問題は次の通りです。 言葉は、そのような

  • として、派手な文字で始まるC
  • É
  • 。Â
  • ...

私が作成したIDが?から始まりますが、ではありません言葉の手紙と一緒に。 奇妙な部分は、それはcsv私が作成すると、派手な手紙の言葉が正しく書かれています。 ?または間違ったエンコーディングを示すその他の記号はありません。

なぜですか?

+1

使用しているPythonのバージョンは何ですか? –

+0

Windowsの場合は、ロケールエンコーディングを使用している可能性があります。 –

+0

@TimMartin 2.7.10、 'Ubuntu Server'に働いています – Stophface

答えて

0

デフォルトでは、Python 2.xの文字列は非Unicodeです - str()は、非Unicode文字列を返します。代わりにunicode()を使用してください。

さらに、組み込みのopen()ではなく、codecs.open()を使用してutf-8エンコーディングを使用してファイルを開く必要があります。

+0

しかし、他の言葉が正しくエンコードされているのはなぜですか? python 3.xへのアップグレードでその問題が解決するでしょうか? – Stophface

+0

@Stophface *他の言葉が正しくエンコードされているのはなぜですか?toId [0]はマルチバイト文字で始まる場合、実際には有効な文字ではなくなります。残りの処理は入力データをそのままコピーします(コンマで区切っても問題はありません)。 – Leon

+0

@Stophface * Python 3.xへのアップグレードでこの問題を解決できますか?はい – Leon

3

是非、あなたが必要とするspecificレガシーC拡張がない限り、Python 2を学ぶべきではありません。

Python 3は(ほとんどの)暗黙的な動作を削除し、エラーを可視にするユニコード/バイト処理を大きく変更します。 open('filename', encoding='utf-8')を使用することは、環境やプラットフォームに依存する既定のエンコーディングであるため、依然として良い方法です。

実際、Python 3であなたのプログラムを実行すると、それをそのまま修正する必要があります。あなたのバグがどこにあるしかし、ここです:myList[0]はすでにstrあるので、

 toId = str(myList[0]) 

これは、何もしません。

  myId = str(toId[0]) + str(counter) 

これはバグです:toIdはUTF-8のデータを含むstr(バイト文字列)です。一度に1文字ずつ処理することを除いて、UTF-8データで何かをしたいことは決してありません。

with open(originalFile, "r") as file: 

これは組み込み関数fileをマスクするため、スタイルエラーです。

io.open(filename, mode, encoding='utf-8')にPythonの2

  1. 変更open(filename, mode)の下で、この実行を行うための2つの変更があります。
  2. 文字列でstr()を呼び出すことを停止します。これは実際にASCIIでエンコードしようとします。

しかし、あなたは本当にPythonの3に切り替える必要があり

あり3とのギャップを埋めることを意図している2.6と2.7に新しいいくつかの作品があり、そのうちの一つは、振る舞いioモジュールであり、すべての素敵な新しい方法で:ユニコードファイルとユニバーサル改行。

~$ python2.7 -c 'import io,sys;print(list(io.open(sys.argv[1],encoding="u8")))' <(printf $'\xc3\x84\r\n\xc3\xb9\r\n') 
[u'\xc4\n', u'\xf9\n'] 
~$ python3 -c 'import sys;print(list(open(sys.argv[1],encoding="u8")))' <(printf $'\xc3\x84\r\n\xc3\xb9\r\n') 
['Ä\n', 'ù\n'] 

これは再び2と3の両方のためのソフトウェアを書くことが役に立つことができ、encoding引数はオプションですが、すべてのプラットフォームでデフォルトのエンコーディングは、環境に依存するので、それは具体的には良いことです。

+1

Python 2ではPy3の 'open()'に一番近い 'io.open()'を使用し、適切なユニバーサルラインサポートを提供するべきです –

+1

ありがとう、私の2to3はちょっと錆びます:) –