这是一个令人费解的例子,但它显示了我正在尝试做的事情。说我有一个字符串:
from string import ascii_uppercase, ascii_lowercase, digits
s = "Testing123"
我想将s
中ascii_uppercase
中显示的所有值替换为大写字母的“L”,所有显示在ascii_lowercase
中的值为“l”表示小写字母,以及digits
中带有“n”的数字。
我现在正在做:
def getpattern(data):
pattern = ""
for c in data:
if c in ascii_uppercase: pattern += "L"; continue
if c in ascii_lowercase: pattern += "l"; continue
if c in digits: pattern += "n"; continue
pattern += "?"
但是,要更换几个列表,这很乏味。我通常更喜欢为这样的事情找到地图类算法,但我很难过。我无法替换任何已经更换过的东西。例如,如果我运行数字1并将其替换为“n”,则下一次迭代可能会将其替换为“l”,因为“n”是一个小写字母。
getpattern("Testing123") == "Lllllllnnn"
答案 0 :(得分:2)
您可以创建一个转换表,将所有大写字母映射到'L'
,将所有小写字母映射到'l'
,将所有数字映射到'n'
。获得此类地图后,您可以将其传递给str.translate()
。
from string import ascii_uppercase, ascii_lowercase, digits, maketrans
s = "Testing123"
intab = ascii_uppercase + ascii_lowercase + digits
outtab = ('L' * 26) + ('l' * 26) + ('n' * 10)
trantab = maketrans(intab, outtab)
print s.translate(trantab)
请注意,在Python 3中没有string.maketrans
函数。相反,您从str对象str.maketrans()
获取方法。详细了解此here和文档here
我不完全确定str.translate()
的内部结构,但我的猜测是,映射为每个字符串字符创建一个长度为256的字符串。当它越过你的字符串时,它会将\x00
翻译为\x00
,\x01
翻译为\x01
等,但A
翻译为L
。这样您就不必检查每个字符是否在翻译词典中。我认为盲目地翻译所有没有分支的角色会带来更好的表现。打印''.join(chr(i) for i in range(256))
进行比较以查看此内容。
答案 1 :(得分:1)
他们使用不同的32块ASCII码,因此您可以这样做:
>>> ''.join(' nLl'[ord(c) // 32] for c in s)
'Lllllllnnn'
您的示例表明您没有其他角色,但如果您这样做,这应该有效:
>>> s = "Testing123 and .?#!-+ äöüß"
>>> ''.join(' nLl'[ord(c) // 32] if c <= 'z' and c.isalnum() else '?' for c in s)
'Lllllllnnn?lll????????????'
答案 2 :(得分:0)
以防您需要处理unicode数据:
import unicodedata
cat = {'Lu':'L', 'Ll':'l', 'Nd':'n'}
def getpattern(data):
return ''.join(cat.get(unicodedata.category(c),c) for c in data)