Python Inconsistent Special Character Storage In String

谁都会走 提交于 2020-03-24 02:44:56

问题


Version is Python 3.7. I've just found out python sometimes will store the character ñ in a string with multiple representations and I'm completely at a loss as to why or how to deal with it.

I'm not sure the best way to show this issue, so I'm just going to show some code output.

I have two strings, s1 and s2 both set to equal 'Dan Peña'

They are both of type string.

I can run the code:

print(s1 == s2) # prints false
print(len(s1)) # prints 8
print(len(s2)) # prints 9
print(type(s1)) # print 'str'
print(type(s2)) # print 'str'
for i in range(len(s1)):
    print(s1[i] + ", " + s2[i])

The output of the loop would be:

D, D
a, a
n, n
 ,  
P, P
e, e
ñ, n
a, ~

So, are there any python methods for dealing with these inconsistencies, or at least some specification as to when python will use which representation?

It would also be nice to know why Python would choose to implement this way.

Edit:

One string is being retrieved from a django database and the other string is from a string obtained from parsing a filename from a list dir call.

from app.models import Model
from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        load_dir = "load_dir_name"
        save_dir = "save_dir"

        files = listdir(load_dir)
        save_file_map = {file[:file.index("_thumbnail.jpg")]: f"{save_dir}/{file}" for file in files}
        for obj in Model.objects.all():
            s1 = obj.title
            save_file_path = save_file_map[s1] # Key error when encountering ñ.

However, when I search through the save_file_map dict I find a key that is exactly the same as s1 except the ñ is encoded as characters n~ rather than character ñ.

Note that the files I load in the above code with list dir are named base on the obj.title field in the first place, so it should be guaranteed that a file with the name is in the load_dir directory.


回答1:


You'll want to normalize the strings to use the same representation. Right now, one of them is using an n character + a tilde character (2 chars), while the other is using a single character representing an n with a tilde.

unicodedata.normalize should do what you want. See the docs here.

You'll want to call this like so: unicodedata.normalize('NFC', s1). 'NFC' tells unicodedata.normalize that you want to use the composed forms for everything, e.g. the 1 char version of . There are other options supplied in the docs besides 'NFC', which one you use is totally up to you.

Now, at what point you normalize is up to you (I don't know how you app is structured). For example you could normalize before inserting into the database, or normalize every time you read from the database.



来源:https://stackoverflow.com/questions/56759851/python-inconsistent-special-character-storage-in-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!