UnicodeDecodeError для соединения

У меня есть список с некоторыми строками (большинство из которых я получил из базы данных sqlite3):

stats_list = ['Statistik \xc3\xb6ver s\xc3\xa5nger\n', 'Antal\tS\xc3\xa5ng', '1\tCarola - Betlehems Stj\xc3\xa4rna', '\n\nStatistik \xc3\xb6ver datak\xc3\xa4llor\n', 'K\xc3\xa4lla\tAntal', 'MANUAL\t1', '\n\nStatistik \xc3\xb6ver \xc3\xb6nskare\n', 'Antal\tId', u'1\tNiclas']

Когда я пытаюсь присоединиться к нему с помощью

return '\n'.join(stats_list)

Я получаю эту ошибку:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

Можно ли понять, почему это происходит, просто просматривая список? Если я перейду через список и распечатаю его на экране, я получаю следующее:

Statistik över sånger

Antal   Sång 
1   Carola - Betlehems Stjärna


Statistik över datakällor

Källa   Antal 
MANUAL  1


Statistik över önskare

Antal   Id
1   Niclas

что и есть то, чего я ожидал, и ошибка не показана. (Специальные символы являются шведскими). ​​

EDIT:

Я попробую:

   return '\n'.join(i.decode('utf8') for i in stats_list)

Но он вернулся:

Traceback (most recent call last):
  File "./CyberJukebox.py", line 489, in on_stats_to_clipboard
    stats = self.jbox.get_stats()
  File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 235, in get_stats
    return self._stats.get_string()
  File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 59, in get_string
    return '\n'.join(i.decode('utf8') for i in stats_list)
  File "/home/nine/dev/python/CyberJukebox/jukebox.py", line 59, in <genexpr>
    return '\n'.join(i.decode('utf8') for i in stats_list)
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 10: ordinal not in range(128)

ИЗМЕНИТЬ 2:

Предлагаемое решение работает для меня в интерпретаторе. Но когда я выполняю код, он не будет работать. Я не могу обмотать голову вокруг этого. Может быть, это что-то очевидное, что мне не хватает, поэтому я вставляю весь метод здесь:

 def get_string(self):
     stats_list = [u'Statistik över sånger\n', u'Antal\tSång']
     stats = sorted([(v, k) for k, v in self.song_stats.iteritems()], reverse=True)
     for row in stats:
         line = '%s\t%s' % row
         stats_list.append(line)

     stats_list.append(u'\n\nStatistik över datakällor\n')
     stats_list.append(u'Källa\tAntal')
     stats = sorted([(k, v) for k, v in self.exts_stats.iteritems()])
     for row in stats:
         line = '%s\t%s' % row
         stats_list.append(line)

     stats_list.append(u'\n\nStatistik över önskare\n')
     stats_list.append(u'Antal\tId')
     stats = sorted([(v, k) for k, v in self.wisher_stats.iteritems() if k != ''], reverse=True)
     for row in stats:
         line = '%s\t%s' % row
         stats_list.append(line)

     return '\n'.join(i.decode('utf8') for i in stats_list)

song_stats, exts_stats и wisher_stats являются словарями в классе.

Ответ 1

Вероятно, ваша проблема заключается в том, что вы смешиваете строки unicode с байтовыми строками.

Код в "Редактировании 2" содержит несколько строк юникода, добавленных в stats_list:

stats_list = [u'Statistik över sånger\n', u'Antal\tSång']

Если вы попытаетесь декодировать эти строки юникода, вы получите UnicodeEncodeError. Это связано с тем, что Python сначала попытается использовать кодировку по умолчанию (обычно "ascii" ), чтобы кодировать строки, прежде чем пытаться их декодировать. Всегда имеет смысл декодировать байтовые строки.

Итак, для начала измените конечную строку в функции на:

return '\n'.join(stats_list)

Теперь вам нужно проверить, являются ли какие-либо другие строки, которые добавлены в stats_list, строками байта, и убедитесь, что они сначала правильно декодируются в строки Unicode.

Итак, поставьте print type(line) после трех строк:

line = '%s\t%s' % row

а затем, где бы он ни печатался <type 'str'>, измените следующую строку на:

stats_list.append(line.decode('utf-8'))

Конечно, если он печатает <type 'unicode'>, нет необходимости изменять следующую строку.

Еще лучшее решение здесь - проверить, как создаются словари song_stats, exts_stats и wisher_stats, и убедитесь, что они всегда содержат строки unicode (или байтовые строки, содержащие только символы ascii).

Ответ 2

Строки кодируются в UTF-8. Вам нужно .decode их на unicode:

>>> 'Statistik \xc3\xb6ver s\xc3\xa5nger\n'.decode('utf-8')
u'Statistik \xf6ver s\xe5nger\n'
>>> print _
Statistik över sånger

Использовать понимание для выполнения этого для всех элементов:

return '\n'.join(x.decode('utf-8') for x in stats_list)

Ответ 3

Python жалуется, что не может преобразовать строку 'Statistik \xc3\xb6ver s\xc3\xa5nger\n' в строку ASCII. Попробуйте префикс всех строк UNICODE с помощью u.

stats_list = [u'Statistik \xc3\xb6ver s\xc3\xa5nger\n', u'Antal\tS\xc3\xa5ng', u'1\tCarola - Betlehems Stj\xc3\xa4rna', u'\n\nStatistik \xc3\xb6ver datak\xc3\xa4llor\n', u'K\xc3\xa4lla\tAntal', u'MANUAL\t1', u'\n\nStatistik \xc3\xb6ver \xc3\xb6nskare\n', u'Antal\tId', u'1\tNiclas']