繁体   English   中英

在Python中将字母转换为数字并执行沿长度的操作序列

[英]Converting letters to numbers and performing sequence of operations along the length in Python

已经做了什么:

  1. 包含固定数量的字母的字符串的每个字母都转换为数字:例如,“ TAAPAS”现在为“ 122324”

    我被迫使用笨拙的代码执行此操作:

     s = s1.replace("A", "2").replace("P", "3").replace("T", "1").replace("S", "4") 

因为当我在较早的论坛上尝试更标准的方法建议时,代码无法修改每个字母:

numerize = {'A':'2', 'P':'3', 'T':'1', 'S':'4'}
for k, v in numerize.iteritems():
    string2 = string1.replace(k, v)

问题1:关于为什么我的情况下此代码不起作用的任何建议? 我什至尝试了以下结果,结果相同:

numerize = {'A':'2', 'P':'3', 'T':'1', 'S':'4'}
for k, v in numerize.iteritems():
    for i in string1: 
         string2 = string1.replace(k, v)

无论如何,接下来我要做什么:

  1. 在我的数字序列“ 122324”上,我想执行一系列定义的数值运算,当到达最后一个运算时,我希望它从头开始...重复多次以达到我整数的末尾。

    例如+,*,/

    这样看起来像:

      y = 1 + 2 * 2 / 3 + 2 * 4 ... 

问题2:必须在数字列表上执行此操作吗? 或者可以像遍历字符串的位置那样遍历整数的位置。 如果不是这样,在转换之前先分割字符串就没什么大不了的。

Q3。 完成此任务的代码是什么? 这类程序是否有名称? 使用关键字“回收”和“数学函数”让我干dry……似乎itertools库没有进行数学运算(因此网页上没有示例)。

谢谢!

最好使用以下翻译来替换字符映射:

from string import maketrans
instr = "APTS"
outstr = "2314"
trans = maketrans(instr, outstr)
print "TAPS".translate(trans)

输出:

1234

获得了这样的输出后,就可以执行以下数值操作:

from string import maketrans
instr = "APTS"
outstr = "2314"
trans = maketrans(instr, outstr)
strNumber = "TAPS".translate(trans)
result=0
for n in strNumber:
    result = result + int(n) #summing all the digits

print result

输出:

10

user3向您展示了如何进行正确的字符翻译。 您的问题之一就是为什么您的代码无法正常工作。 看看发生了什么:

>>> string1 = "TAAPAS"
>>> for k, v in numerize.iteritems():
...     string2 = string1.replace(k, v)
...     print string2
...
TAAPA4
TAA3AS
T22P2S
1AAPAS

在每次迭代中,您都使用相同的字符串重新启动,因此仅保留了最后的替换操作(字符串是不可变的 ,因此.replace()始终返回新的字符串,而不是更改正在处理的字符串)。 如果您使用过string1 = string1.replace(k, v) ,那么结果将是正确的。

>>> eval_expr(interlace(letters2numbers("TAAPAS"), cycle("+*/")))
10.333333333333332

问题1:关于为什么我的情况下此代码不起作用的任何建议?

字符串在Python中是不可变的。 string1.replace()不会修改string1 ,并且每次迭代都会覆盖string2

问题2:必须在数字列表上执行此操作吗?

可以。您可以以字符串形式创建算术表达式,而无需先转换为int ,首先转换为float

Q3。 完成此任务的代码是什么? 这类程序是否有名称?

  • "TAAPAS""122324"步骤是翻译/编码。 您可以使用@ user3建议的 .translate()方法实现翻译步骤:

     import string table = string.maketrans("TAPS", "1234") def letters2numbers(letters): """ >>> letters2numbers("TAAPAS") '122324' """ return letters.translate(table) 
  • "122324" + cycle("+*/")"1 + 2 * 2 / 3 + 2 * 4"是隔行扫描的:

     def interlace(left, right): """ >>> from itertools import cycle >>> interlace("122324", cycle("+*/")) '1+ 2* 2/ 3+ 2* 4' """ return " ".join(a+b for a, b in zip(left, right))[:-1] 

    itertools.cycle("+*/")无限次重复该序列,直到zip()停止。 它在使用[:-1]砍掉的末尾添加了不必要的运算符。

  • "1 + 2 * 2 / 3 + 2 * 4"10.(3)是算术评估:

     >>> eval_expr('1+ 2* 2/ 3+ 2* 4') 10.333333333333332 

    其中eval_expr()是简单数学表达式的安全eval()模拟

或者,您可以将所有步骤组合为一个函数:

from itertools import cycle
from operator import add, sub, mul, floordiv

def eval_letters(letters, operators,
                 numerize={'A': 2, 'P': 3, 'T': 1, 'S': 4},
                 functions={'+': add, '-': sub, '*': mul, '/': floordiv}):
    """
    >>> eval_letters("TAAPAS", "+*/")
    16
    """
    numbers = (numerize[c] for c in letters)
    operators = cycle(operators) # repeat ad infinitum
    result = next(numbers)
    for n, op in zip(numbers, operators):
        result = functions[op](result, n)
    return result

注意:这里我为/运算符选择了floordivfloordiv 3/2==1 ),而不是truediv ()使用的eval_expr() 3/2==1.5 eval_expr()

您可以以更简单的方式使用数字化

numerize = {'A':'2', 'P':'3', 'T':'1', 'S':'4'}
string2 = ""
for c in "TAAPAS":
    string2 += numerize[c]
print string2

所有给出的答案(格林尼治标准时间@ 6:30)仅适用于一个字符串。

如果你有编码与,每串,你的代码分配提供多串1的第一个字母字符串中, 2中输入字符串等不同的第二封信,你可以试用一下下面的函数。

def numerize(s):
    nd = 0
    copy = s[::]
    for i  in range(len(s)):
        c = copy[i]
        if c.isdigit(): continue
        nd = nd + 1
        if nd > 9 :
            print "Too many different characters in \"%s\"." % s
            return None # here you may want to throw
        copy = copy.replace(c,repr(nd))
    return copy

print numerize('asdeaswes')

我想说的一个默认假设是输入字符串不包含任何数字。 您可能需要在处理之前检查每个字符,例如,唯一的合法字符是拉丁大写字母A到Z。

ps:如果您需要一个整数列表代替一串数字,

 s/return copy/return [int(d) for d in copy]/

pps:关于数值后处理,imo最好遵循JF Sebastian的建议

eval_expr(interlace(numerize("TAAPAS"), cycle("+*/")))

而不是自己重新发明轮子...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM