python: ValueError: неверный литерал для int () с основанием 10: '' - PullRequest
1 голос
/ 16 сентября 2011

У меня есть текстовый файл, который содержит запись типа

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

Я написал эту программу для чтения: (Извините, отступ здесь немного запутан)

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: ''

Забавно то, что он работает просто отлично, считывая данные того же формата из другого файла .. На самом деле во время публикации этого вопроса, я заметил что-то странное .. Запись 70154 :: 308933 :: 3 у каждого числа есть пробел. между 7 пробел 0 пробел 1 пробел 5 пробел 4 пробел :: пробел 3 ... Но текстовый файл выглядит нормально .. :( при копировании только это показывает эту природу .. В любом случае ... но любая подсказка, что происходит. Спасибо

Ответы [ 2 ]

3 голосов
/ 16 сентября 2011

"Пробелы", которые вы видите, выглядят как NUL ("\ x00").Вероятность того, что ваш файл закодирован в UTF-16, UTF-16LE или UTF-16BE, составляет 99,9%.Если это одноразовый файл, просто откройте его с помощью Блокнота и сохраните как «ANSI», а не «Unicode» и не «Unicode bigendian».Однако, если вам нужно обработать его как есть, вам нужно знать / определить, что такое кодировка.Чтобы выяснить, что, сделайте следующее:

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

и сравните исходную информацию со следующим:

>>> 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.

Вы можете избежать жесткого кодирования резервной кодировки:

>>> import locale
>>> locale.getpreferredencoding()
'cp1252'

Ваш код чтения строки будет выглядеть следующим образом:

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

О, и линии будут unicode объектами ... если это вызывает у вас проблемы, задайте еще один вопрос.

2 голосов
/ 16 сентября 2011

Отладка 101: просто измените строку:

words = words.strip().split()

до:

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

и посмотри, что получится.

Я упомяну пару вещей. Если у вас есть литерал UserId::... в файле, и вы пытаетесь его обработать, вам не нужно будет преобразовывать его в целое число.

И ... необычная строка:

if n is not 1:

Я бы, наверное, написал как:

if n != 1:

Если, как вы указываете в своем комментарии, вы в конечном итоге видите:

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

тогда я буду проверять ваш входной файл на двоичные (нетекстовые) данные. Вы никогда не должны получать эту двоичную информацию, если вы просто читаете текст и обрезаете / разбиваете.

И поскольку вы утверждаете, что между цифрами, похоже, есть пробелы, вы должны выполнить шестнадцатеричный дамп файла, чтобы выяснить, что на самом деле там. Например, это может быть строка в кодировке UTF-16 Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...