Проблема с чтением строки с символами, отличными от ascii, в python 3

Я пытаюсь прочитать изображения из набора данных WikiArt. Однако я не могу загрузить некоторые изображения, содержащие символы, отличные от ascii: Например: fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg' хотя файл существует в каталоге. Я также сравнил имя выходной строки из os.listdir() и из FileNotFoundError: No such file: '/wiki_art_paintings/rescaled_600px_max_side/Expressionism/fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg' при выполнении 'fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg' == 'fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'. Вывод Ложь.

В чем здесь может быть проблема?

Пожалуйста, добавьте свой код и правильный вывод трассировки ошибок

Or Y 23.12.2020 07:40

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

furas 23.12.2020 07:40

когда я проверяю символ за символом, он показывает мне ã как два символа a ̃ - В юникоде это возможно

furas 23.12.2020 07:45

@furas, да, как я могу это исправить?

kilich 23.12.2020 07:50

как получить эти файлы? Возможно, это можно было бы исправить, когда вы получите файлы и поместите их на диск. А какую систему вы используете? Возможно, проблема в системе - однажды у меня была проблема с MacOS, потому что она использовала UTF-8 в другом стандарте.

furas 23.12.2020 07:53

@furas, у меня есть несколько папок с изображениями и файл csv, который содержит некоторые данные + ссылку на изображения в этих папках в виде строки

kilich 23.12.2020 07:58

Я нашел только старый код, который тестирует другой метод преобразования имен файлов MacOS в Unicode в Linux Unicode macosx-linux-UTF-8 Используя функцию unidecode(), я могу преобразовать обе версии в одно и то же fa(c)lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg, чтобы их можно было сравнить (== даст True ), но по-прежнему бесполезно получать имя из файла и создавать имя файла для открытия изображения.

furas 23.12.2020 08:07

Швы должны быть связаны с нормализованными/денормализованными формами. Взгляните на этот stackoverflow.com/questions/3126929/…

mgruber4 23.12.2020 09:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
294
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Две строки не совпадают. Смотреть:

> ciao='fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'.encode('utf-8')       
> bye='fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'.encode('utf-8')        
> ciao.hex() 
 '6661cc83c2a96c69782d64656c2d6d61726c655f6e752d6167656e6f75696c6c2d7375722d666f6e642d626c65752d313933372e6a7067'
> bye.hex()  
 '66c3a3c2a96c69782d64656c2d6d61726c655f6e752d6167656e6f75696c6c2d7375722d666f6e642d626c65752d313933372e6a7067'
> ciao2='fa'.encode('utf-8')
> bye2='f'.encode('utf-8')
> ciao2.hex()
 '6661'
> bye2.hex() 
 '66'

кажется, что вокруг «f» есть скрытый символ. Кажется, "а"

хорошее описание, но это место для решений, и я не вижу никакого решения в вашем ответе

furas 23.12.2020 08:00

Проблема в том, что имя вашего файла содержит é. Процесс, создавший файл, записал имя в кодировке UTF-8, которой требуется 2 байта для представления é. Ваша файловая система не понимает UTF-8, поэтому она отображает 2 байта, как если бы они были закодированы как latin-1. Попробуйте поставить é в имени файла при вызове open() вместо ã©.

BoarGules 23.12.2020 09:06
Ответ принят как подходящий

Проблема в том, что в Unicode вы можете использовать один символ или создать какой-то персонаж как комбинацию двух других персонажей, и у вас есть обе ситуации в двух разных местах. В одном месте у вас есть некоторые символы как отдельные символы (с одним кодом), а в другом месте у вас есть символы как комбинации двух других символов (с двумя кодами). Вы можете увидеть даже разницу, когда используете len() для обеих строк. В вашем примере одна версия имеет длину 53, а другая — 52

Кажется, вы можете преобразовать одно имя в другое, используя unicodedata.normalize() с одним из вариантов NFC, NFKC, NFD, NFKD. Таким образом, вы должны проверить, какой из них будет работать для вас.

В одном направлении вам может понадобиться NFC или NFKC, в другом направлении вам может понадобиться NFD или NFKD.

Вы также можете использовать unidecode для создания текста без родных символов: fa(c)lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg но это может быть не так полезно для вас.

import unicodedata
from unidecode import unidecode

a = 'fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'
b = 'fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'

print('a:', a)
print('b:', b)

print('--- len ---')
print('len(a):', len(a))
print('len(b):', len(b))

print('--- encode ---')
print('a.encode:', a.encode('utf-8'))
print('b.encode:', b.encode('utf-8'))

print('--- a == normalize(b) ---')
print('NFC: ', a == unicodedata.normalize('NFC', b) )
print('NFKC:', a == unicodedata.normalize('NFKC', b) )
print('NFD: ', a == unicodedata.normalize('NFD', b) )
print('NFKD:', a == unicodedata.normalize('NFKD', b) )

print('--- b == normalize(a) ---')
print('NFC: ', b == unicodedata.normalize('NFC', a) )
print('NFKC:', b == unicodedata.normalize('NFKC', a) )
print('NFD: ', b == unicodedata.normalize('NFD', a) )
print('NFKD:', b == unicodedata.normalize('NFKD', a) )

print('--- unidecode ---')
print('a:', unidecode(a))
print('b:', unidecode(b))

Результат:

a: fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg
b: fã©lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg
--- len ---
len(a): 53
len(b): 52
--- encode ---
a.encode: b'fa\xcc\x83\xc2\xa9lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'
b.encode: b'f\xc3\xa3\xc2\xa9lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg'
--- a == normalize(b) ---
NFC:  False
NFKC: False
NFD:  True
NFKD: True
--- b == normalize(a) ---
NFC:  True
NFKC: True
NFD:  False
NFKD: False
--- unidecode ---
a: fa(c)lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg
b: fa(c)lix-del-marle_nu-agenouill-sur-fond-bleu-1937.jpg

Я встречал символы как комбинацию двух других символов только тогда, когда мне нужно перенести файлы MacOS в другую систему.


Док: unicodedata

Лист Python: Юникод

Stackoverflow: Нормализация Unicode

спасибо, @furas. Просто введение нормализации помогло мне решить эту проблему.

kilich 23.12.2020 13:23

Другие вопросы по теме