Я хочу объединить список различных объектов Python в одну строку. Объекты могут быть буквально чем угодно. Я думал, что мог бы просто сделать это, используя следующий код:

' '.join([str(x) for x in the_list])

Но, к сожалению, это иногда дает мне UnicodeEncodeError:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 80: ordinal not in range(128)

В этом ответе SO я нашел человека, который сказал, что мне нужно использовать .encode('utf-8'), поэтому я изменил свой код на этот:

' '.join([x.encode('utf-8') for x in the_list])

Но если объекты не являются строками или юникодами, а, например, int s, я получаю AttributeError: 'int' object has no attribute 'encode'. Так что это означает, что мне нужно использовать какой-то оператор if, чтобы проверить, какой это тип и как его преобразовать. Но когда я должен использовать .encode('utf-8') и когда я должен использовать str()?

Было бы еще лучше, если бы я мог сделать для этого какой-то вкладыш, но я не знаю, как? Кто-нибудь еще знает? Все советы приветствуются!

7
kramer65 17 Дек 2015 в 19:52

3 ответа

Лучший ответ

Python 2.x использует repr(). Python 3.x использует repr(), если вы не возражаете против не-ASCII Unicode в результате, или ascii(), если вы делаете:

>>> a=1             # integer
>>> class X: pass
...
>>> x=X()           # class
>>> y='\u5000'      # Unicode string
>>> z=b'\xa0'       # non-ASCII byte string
>>> ' '.join(ascii(i) for i in (a,x,y,z))
"1 <__main__.X object at 0x0000000002974B38> '\\u5000' b'\\xa0'"

Пример различий между 2.X и 3.X repr() и 3.X ascii():

>>> # Python 3
>>> s = 'pingüino' # Unicode string
>>> s
'pingüino'
>>> repr(s)
"'pingüino'"
>>> print(repr(s))
'pingüino'
>>> ascii(s)
"'ping\\xfcino'"
>>> print(ascii(s))
'ping\xfcino'    

>>> # Python 2
>>> s = u'pingüino'
>>> s
u'ping\xfcino'
>>> repr(s)
"u'ping\\xfcino'"
>>> print(repr(s))
u'ping\xfcino'
6
Mark Tolonen 18 Дек 2015 в 20:34

Вы можете попробовать объединить троичного оператора с вашим текущим однострочником. Также join прекрасно работает с генератором, поэтому я не думаю, что вам нужно создавать список. Что-то типа

' '.join(x.encode('utf-8') if isinstance(x, basestring) else str(x)
         for x in the_list)
0
James J. 17 Дек 2015 в 17:07

Вместо этого вы можете попробовать join использовать объект Unicode ..

u' '.join(unicode(x) for x in thelist)

Или то, что у вас было раньше, будет хорошо работать в python3. Просто не забудьте:

  1. рано декодировать
  2. Юникод везде
  3. закодировать поздно

Подробнее см. В этом выступлении.

1
Chad S. 17 Дек 2015 в 17:32