13

我正在寻找一种更有效的方法来总结给定字符串中所有字符的ASCII值,仅使用标准 python(最好是 2.7)。

目前我有:

print sum(ord(ch) for ch in text)

我想强调一下,我在上面写的这个问题的主要重点和方面。

以下是这个问题的不太重要的方面,应该这样对待

那我问它干嘛?!我已经将这种方法与嵌入一个简单的 C 代码函数进行了比较,该函数在此处使用 PyInline 执行相同的操作,似乎一个简单的 C 嵌入函数要快 17 倍。

如果没有比我建议的更快的 Python 方法(仅使用标准 Python),那么 Python 开发人员没有在核心中添加这样的实现似乎很奇怪。

建议答案的当前结果。在我的 Windows 7、i-7、Python 2.7 上:

 text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 sum(ord(ch) for ch in text)
 >> 0.00521324663262
 sum(array.array("B", text))
 >> 0.0010040770317
 sum(map(ord, text ))
 >> 0.00427160369234
 sum(bytearray(text))
 >> 0.000864669402933

 C-code embedded:
 >> 0.000272828426841
4

4 回答 4

21

您可以使用中间体bytearray来加快速度:

>>> sum(bytearray("abcdefgh"))
804

这并不比生成器快 17 倍——它涉及创建中间体bytearray,并且sum仍然必须迭代 Python 整数对象——但在我的机器上,它确实将 8 字符字符串的求和速度从 2μs 加快到大约 700ns。如果这个球场的时间对于您的用例来说仍然太低效,那么您可能无论如何都应该用 C 编写应用程序的速度关键部分。

如果您的字符串足够大,并且可以使用numpy,则可以通过使用直接引用字符串的缓冲区来避免创建临时副本numpy.frombuffer

>>> import numpy as np
>>> np.frombuffer("abcdefgh", "uint8").sum()
804

对于较小的字符串,这比临时数组慢,因为 numpy 的视图创建机制很复杂。然而,对于足够大的字符串,这种frombuffer方法开始得到回报,而且它当然总是产生更少的垃圾。在我的机器上,截止点是大约 200 个字符的字符串大小。

另请参阅 Guido 的经典文章Python 优化轶事。虽然它的一些特定技术现在可能已经过时,但如何考虑Python 优化的一般课程仍然非常相关。


您可以使用该timeit模块对不同方法进行计时:

$ python -m timeit -s 's = "a" * 20' 'sum(ord(ch) for ch in s)' 
100000 loops, best of 3: 3.85 usec per loop
$ python -m timeit -s 's = "a" * 20' 'sum(bytearray(s))'
1000000 loops, best of 3: 1.05 usec per loop
$ python -m timeit -s 'from numpy import frombuffer; s = "a" * 20' \
                      'frombuffer(s, "uint8").sum()' 
100000 loops, best of 3: 4.8 usec per loop
于 2012-09-19T09:51:00.507 回答
11

您可以通过删除生成器的创建来加快它的速度(约 40% ish,但远不及本机 C 的速度)......

代替:

sum(ord(c) for c in string)

做:

sum(map(ord, string))

时间:

>>> timeit.timeit(stmt="sum(map(ord, 'abcdefgh'))")
# TP: 1.5709713941578798
# JC: 1.425781011581421
>>> timeit.timeit(stmt="sum(ord(c) for c in 'abcdefgh')")
# TP: 1.7807035140629637
# JC: 1.9981679916381836
于 2012-09-19T09:57:28.060 回答
3
print sum(map(ord,my_string))

这将是最简单的。

于 2017-02-18T04:32:14.747 回答
0

打印字符串中字符的 ASCII 值的总和

首先将所有字符串转换为列表,每个单词都分开。然后使用 ord() 函数将每个字符转换为 ascii 并将它们存储在列表中,然后添加所有列表值。

str1 = input("Please Enter your Own String : ")
li=[] 
li[:0]=str1 
print(li)
result=[]
for i in range(len(li)):
    result.append(ord(li[i]))
    result = list(set(result))
print(result)   
final=sum(result) 
print("The sum of the your string '{}'is: {}".format(str1,final))
于 2020-11-23T08:23:28.063 回答