2011-09-16 7 views
1

私はのpython:ValueErrorを:int型のための無効なリテラル()ベース10と:「」

70154::308933::3 
UserId::ProductId::Score 

のようなエントリを含むテキストファイルを持っている私が読むためにこのプログラムを書いた: (申し訳ありませんindendetionは少し混乱していますここまで)

def generateSyntheticData(fileName): 
dataDict = {} 
# rowDict = [] 
innerDict = {} 


try: 
    # for key in range(5): 
    # count = 0 
    myFile = open(fileName) 
    c = 0 
     #del innerDict[0:len(innerDict)] 

    for line in myFile: 
     c += 1 
     #line = str(line) 
     n = len(line) 
     #print 'n: ',n 
     if n is not 1: 
     # if c%100 ==0: print "%d: "%c, " entries read so far" 
     # words = line.replace(' ','_') 
      words = line.replace('::',' ') 

      words = words.strip().split() 


      #print 'userid: ', words[0] 
      userId = int(words[0]) # i get error here 
      movieId = int (words[1]) 
      rating =float(words[2]) 
      print "userId: ", userId, " productId: ", movieId," :rating: ", rating 
      #print words 
      #words = words.replace('_', ' ') 
      innerDict = dataDict.setdefault(userId,{}) 
      innerDict[movieId] = rating 
      dataDict[userId] = (innerDict) 
      innerDict = {} 
except IOError as (errno,strerror): 
    print "I/O error({0}) :{1} ".format(errno,strerror) 

finally: 
    myFile.close() 
print "total ratings read from file",fileName," :%d " %c 
return dataDict 

しかし、私はエラーを取得:

ValueError: invalid literal for int() with base 10: '' 

おかしい事は、それがworkiで、あります他のファイルから同じフォーマットのデータを読み込んでいるだけです。 実際にこの質問を投稿しているうちに、私は何か変わったことに気付きました。 エントリ70154 :: 308933 :: 3 各数字にはスペース7 1スペース5スペース4スペース::スペース3 ... テキストファイルをきれいに見えます。:(コピー貼り付け時には、この性質が表示されます.. とにかく..何か手掛かりがあります。 おかげ

+0

どのようにテキストファイルを読んでいますか?あなたのコードを投稿してください。 – jozzas

答えて

3

あなたが見ている「スペース」はNUL(「\ x00」)のように見えます。ファイルがUTF-16、UTF-16LE、またはUTF-16BEでエンコードされる可能性は99.9%です。これがワンオフファイルの場合は、メモ帳で開き、 "Unicode"ではなく "Unicode bigendian"ではなく "ANSI"として保存してください。ただし、そのまま処理する必要がある場合は、エンコーディングが何であるかを知る/検出する必要があります。

print repr(open("yourfile.txt", "rb").read(20)) 

をし、次に出力のsrtartを比較します:調べるにこれ、これを行う

>>> ucode = u"70154:" 
>>> for sfx in ["", "LE", "BE"]: 
...  enc = "UTF-16" + sfx 
...  print enc, repr(ucode.encode(enc)) 
... 
UTF-16 '\xff\xfe7\x000\x001\x005\x004\x00:\x00' 
UTF-16LE '7\x000\x001\x005\x004\x00:\x00' 
UTF-16BE '\x007\x000\x001\x005\x004\x00:' 
>>> 

あなたが最初の2つのバイトを調べて、あなたの目的には十分だ検出器を作ることができます:

[pseudocode] 
if f2b in `"\xff\xfe\xff"`: UTF-16 
elif f2b[1] == `"\x00"`: UTF-16LE 
elif f2b[0] == `"\x00"`: UTF-16BE 
else: cp1252 or UTF-8 or whatever else is prevalent in your neck of the woods. 

あなたは代替エンコーディングをハードコーディングを避けることができます:

を210

あなたのライン読みのコードは次のようになります。

rawbytes = open(myFile, "rb").read() 
enc = detect_encoding(rawbytes[:2]) 
for line in rawbytes.decode(enc).splitlines(): 
    # whatever 

ああ、そしてラインはunicodeオブジェクトになります...それはあなたに問題を与える場合は、別の質問をします。

+0

ああ男!!!素晴らしい..これは問題を解決した..ありがとう! – Fraz

+0

@Fraz:喜んで助けることができました。どの部分が手伝ってくれましたか?メモ帳のトリックやPythonコードのもの? –

+0

umm ..私は実際にこの作業をしたいと思っていました。代わりにwords = words.replace( '\ x00'、 ''):)のような何かをしました:) – Fraz

2

デバッグ101:単純に行を変更します。

words = words.strip().split() 

へ:

words = words.strip().split() 
print words 

と出てくるものを参照してください。

私はいくつかのことを言及します。ファイル内にリテラルUserId::...があり、それを処理しようとすると、それを整数に変換しようとするのは親切ではありません。

そして...珍しいライン:あなたがあなたのコメントに示すように、あなたが見て終わる、場合

if n != 1: 

if n is not 1: 

私はおそらくとして書きます

['\x007\x000\x001\x005\x004\x00', '\x003\x000\x008\x009\x003\x003\x00', '3'] 

あなたのインプをチェックしていますバイナリ(非テキスト)データ用のtファイル。テキストを読んでトリミング/分割するだけであれば、バイナリ情報で終わるべきではありません。

数字の間にスペースがあるように見えるので、実際にそこにあるものを見つけるためにファイルの16進ダンプを実行する必要があります。たとえば、UTF-16 Unicode文字列である可能性があります。

+0

実際に見ることができるように、['\ x007 \ x000 \ x001 \ x005 \ x004 \ x00'、 '\ x003 \ x000 \ x008 \ x009 \ x003 \ x003 \ x00'、 'これはネストされたdict ..だから私はそれが私に鍵のアドレスを与えると思われる? – Fraz

+1

@Fraz、もしあなたが示しているように 'line'が_text_ファイルから来ているならば、あなたは' words'でそのようなもので決して終わるべきではありません。それはテキストでなければなりません。入力ファイルを確認する必要があります。 – paxdiablo

+1

@Fraz私はpaxdiabloに同意しますが、おそらく問題は入力データのエンコードです。 @pax - あなたは '!='を使用するのは正しいですが、 'not is'はCPythonで動作します。なぜなら、0-255は中断され、すべての' 1 'は同じアイデンティティを持つからです。 – agf

関連する問題