一尘不染

str.replace(..)。replace(..)ad nauseam是Python中的标准习语吗?

python

例如,假设我想要一个函数来转义用于HTML的字符串(如Django的转义过滤器):

    def escape(string):
        """
        Returns the given string with ampersands, quotes and angle 
        brackets encoded.
        """
        return string.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace("'", '&#39;').replace('"', '&quot;')

这可以工作,但是很快就会变得丑陋,并且算法性能似乎很差(在此示例中,字符串被重复遍历了5次)。最好是这样的:

    def escape(string):
        """
        Returns the given string with ampersands, quotes and angle 
        brackets encoded.
        """
        # Note that ampersands must be escaped first; the rest can be escaped in 
        # any order.
        return replace_multi(string.replace('&', '&amp;'),
                             {'<': '&lt;', '>': '&gt;', 
                              "'": '&#39;', '"': '&quot;'})

是否存在这样的功能,还是使用我之前编写的标准Python习惯用法?


阅读 179

收藏
2021-01-20

共1个答案

一尘不染

您是否有一个运行速度太慢的应用程序,并且对其进行了概要分析,发现像该代码片段这样的行导致其运行缓慢?瓶颈发生在意外的地方。

当前代码段遍历字符串5次,每次都做一件事。您建议遍历一次,可能每次都要做五件事(或者至少每次都要做某事)。尚不清楚这是否会自动对我做得更好。当前使用的算法为O(n * m)(假设字符串的长度比规则中的填充长),其中n是字符串的长度,m是替换规则的数量。我认为,您可以将算法复杂度降低到O(n * log(m)),在特定情况下,我们将原来的东西都只是一个字符(但在多次调用的情况下,则不是)到replaceO)(n),但这无关紧要,因为 m为5,
n是无界的

如果m保持恒定,则两个解的复杂度实际上都为O(n)。对我来说尚不清楚,尝试将五张简单的通行证变成一张复杂的通行证将是一项有价值的任务,而我目前无法猜测其实际时间。如果有什么可以使它更好地扩展的,我会认为这是更有价值的任务。

只通过一次而不是连续通过所有操作,还需要回答有关如何处理冲突规则以及如何应用它们的问题。这些问题的解决方案是一连串的replace

2021-01-20