我在mac os x 10.6上运行python 2.7,文件在utf8,终端在utf8。
我想在每次出现在给定字符串中的元音å,ä或ö之后添加句点。
以下是我想要做的愚蠢版本:
# coding: utf8
a = 'change these letters äöå'
b = map( (lambda x: a.replace(x, "{0}.".format(x))), 'åäö')
for c in b:
print c
产生以下输出:
change these letters ?.??.??.?
change these letters äöå.
change these letters ?.??.??.?
change these letters ä.öå
change these letters ?.??.??.?
change these letters äö.å
为什么我会带问号线?经过进一步研究,这样做会产生相同的问号。
# coding: utf8
for letter in 'åäö':
print letter
输出:
?
?
?
?
?
?
但是明确地添加u之前给出了
# coding: utf8
for letter in u'åäö':
print letter
输出:
å
ä
ö
将字符串明确解码并编码回utf8
仍会产生问号。这里有什么问题?什么在这个循环中徘徊?
旁注:在愚蠢的例子中,你会看到我想要做的事情。实际上我正在使用一个保存字符串的对象,以便映射的操作发生在同一个字符串上。因此,map()
调用实际上每次使用一个新元音调用对象的方法,从而更新保存在对象中的字符串。对象的方法使用map
的第二个参数中的元音执行替换,并更新存储的字符串。
答案 0 :(得分:2)
您将匿名函数映射到字符串上;你应该将它映射到字符串列表。 Python解释器仍将接受您提供的指令,将字符串视为序列并将lambda应用于该序列的每个组件。但在这种情况下,组件是字符串的单个字节,每个unicode字符都是两个字节。所以替换执行六次。
此外,在这些迭代中的三个中,替换是用0xc3
替换unicode前缀字节äöå
(在0xc3.
中发生三次)的相同操作,这打破了字符串a
中的字符编码并生成原始字节乱码。在其他三次迭代中,您将unicode char的第二个字节替换为该字节后跟一个句点,因此生成的字符串仍包含相关字符的字节序列,您将获得所需的结果。但那是而不是,因为你用一个字符替换整个字符后跟一段时间。
比较
>>> a = 'change these letters äöå'
>>> b = map( (lambda x: a.replace(x, "{0}.".format(x))), 'å ä ö'.split())
>>> for c in b:
... print c
...
change these letters äöå.
change these letters ä.öå
change these letters äö.å
答案 1 :(得分:1)
您正在迭代字节字符串中的字节。由于编码为UTF-8的非ASCII字符使用多个字节,因此您将破坏字符。如果必须遍历字符,则迭代unicode
的字符。