将iterable中的值替换为另一个iterable的值到相同的值

时间:2016-01-28 03:43:26

标签: python algorithm

这是一个令人费解的例子,但它显示了我正在尝试做的事情。说我有一个字符串:

from string import ascii_uppercase, ascii_lowercase, digits
s = "Testing123"

我想将sascii_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"

3 个答案:

答案 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)