[英]Converting letters to numbers and performing sequence of operations along the length in Python
已经做了什么:
包含固定数量的字母的字符串的每个字母都转换为数字:例如,“ 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)
无论如何,接下来我要做什么:
在我的数字序列“ 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
或者,您可以将所有步骤组合为一个函数:
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
注意:这里我为/
运算符选择了floordiv
( floordiv
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.