当前位置: 首页 > 面试题库 >

如何在Python中将一个字符串附加到另一个字符串?

凌琦
2023-03-14
问题内容

除了以下内容外,我想要一种有效的方法来在Python中将一个字符串附加到另一个字符串。

var1 = "foo"
var2 = "bar"
var3 = var1 + var2

有什么好的内置方法可以使用吗?


问题答案:

如果你仅对一个字符串有一个引用,并且将另一个字符串连接到末尾,则CPython现在会对此进行特殊处理,并尝试在适当位置扩展该字符串。

最终结果是将操作摊销O(n)。

例如

s = ""
for i in range(n):
    s+=str(i)

过去是O(n ^ 2),但现在是O(n)。

从源(bytesobject.c):

void
PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
{
    PyBytes_Concat(pv, w);
    Py_XDECREF(w);
}


/* The following function breaks the notion that strings are immutable:
   it changes the size of a string.  We get away with this only if there
   is only one module referencing the object.  You can also think of it
   as creating a new string object and destroying the old one, only
   more efficiently.  In any case, don't use this if the string may
   already be known to some other part of the code...
   Note that if there's not enough memory to resize the string, the original
   string object at *pv is deallocated, *pv is set to NULL, an "out of
   memory" exception is set, and -1 is returned.  Else (on success) 0 is
   returned, and the value in *pv may or may not be the same as on input.
   As always, an extra byte is allocated for a trailing \0 byte (newsize
   does *not* include that), and a trailing \0 byte is stored.
*/

int
_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
{
    register PyObject *v;
    register PyBytesObject *sv;
    v = *pv;
    if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) {
        *pv = 0;
        Py_DECREF(v);
        PyErr_BadInternalCall();
        return -1;
    }
    /* XXX UNREF/NEWREF interface should be more symmetrical */
    _Py_DEC_REFTOTAL;
    _Py_ForgetReference(v);
    *pv = (PyObject *)
        PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize);
    if (*pv == NULL) {
        PyObject_Del(v);
        PyErr_NoMemory();
        return -1;
    }
    _Py_NewReference(*pv);
    sv = (PyBytesObject *) *pv;
    Py_SIZE(sv) = newsize;
    sv->ob_sval[newsize] = '\0';
    sv->ob_shash = -1;          /* invalidate cached hash value */
    return 0;
}

凭经验进行验证很容易。

$ python -m timeit -s"s=''" "for i in xrange(10):s+='a'"
1000000 loops, best of 3: 1.85 usec per loop
$ python -m timeit -s"s=''" "for i in xrange(100):s+='a'"
10000 loops, best of 3: 16.8 usec per loop
$ python -m timeit -s"s=''" "for i in xrange(1000):s+='a'"
10000 loops, best of 3: 158 usec per loop
$ python -m timeit -s"s=''" "for i in xrange(10000):s+='a'"
1000 loops, best of 3: 1.71 msec per loop
$ python -m timeit -s"s=''" "for i in xrange(100000):s+='a'"
10 loops, best of 3: 14.6 msec per loop
$ python -m timeit -s"s=''" "for i in xrange(1000000):s+='a'"
10 loops, best of 3: 173 msec per loop

不过,请务必注意,此优化不是Python规范的一部分。据我所知,它仅在cPython实现中。例如,对pypy或jython进行的相同经验测试可能会显示较旧的O(n ** 2)性能。

$ pypy -m timeit -s"s=''" "for i in xrange(10):s+='a'"
10000 loops, best of 3: 90.8 usec per loop
$ pypy -m timeit -s"s=''" "for i in xrange(100):s+='a'"
1000 loops, best of 3: 896 usec per loop
$ pypy -m timeit -s"s=''" "for i in xrange(1000):s+='a'"
100 loops, best of 3: 9.03 msec per loop
$ pypy -m timeit -s"s=''" "for i in xrange(10000):s+='a'"
10 loops, best of 3: 89.5 msec per loop

到目前为止一切顺利,但随后,

$ pypy -m timeit -s"s=''" "for i in xrange(100000):s+='a'"
10 loops, best of 3: 12.8 sec per loop

哎呀,甚至比二次还差。因此,pypy可以在短字符串上做得很好,但是在较大的字符串上却表现不佳。



 类似资料:
  • 我有两个字符串str1和str2。我试图用字符把一些字母从一个字符串复制到另一个字符串。我知道我可以使用字符串复制,但我想要一些字符,而不是全部字符。 在Java中,如何将子字符串从一个字符串复制到另一个字符串?

  • 问题内容: 我是Java的新手,为了实践起见,我试图创建一个十六进制到十进制的数字转换器,因为我已经成功地制作了一个二进制到十进制的转换器。 我遇到的问题基本上是将一个字符串中的给定字符与另一个字符串进行比较。这就是我定义要比较的当前字符的方式: 这是我尝试比较角色的方法: 当我尝试通过仅输入数字(例如12)来运行代码时,它可以工作,但是当我尝试使用“ b”时,会出现一个奇怪的错误。这是运行程序的

  • 例如: 字符串1=helloworld字符串2=asdfuvjerhelloworld 这应该是真的。 另一个例子:字符串1=helloworld字符串2=lshewodxzr 这也应该是真的。 所以我正在研究如何创建一个方法,它将返回一个布尔值,检查第二个字符串是否包含第一个字符串中的字母。在第二个示例中,string2只有一次字母l,尽管字母l在string1中出现了三次,但仍然返回true。

  • 如何检查一个字符串是否在另一个字符串中,但匹配项需要在前面,而不是中间或最后。例如,a="

  • 我正在研究将字符串从一个字符集转换为另一个字符集,阅读了很多关于它的示例,最终找到了下面的代码,这对我来说很好,作为一个字符集编码的新手,我想知道,这是否是正确的方法。 要将字符串从ASCII转换为EBCDIC,我必须执行以下操作: 要将EBCDIC转换为ASCII,我必须:

  • 本文向大家介绍如何检查Python的另一个字符串中是否存在多个字符串?,包括了如何检查Python的另一个字符串中是否存在多个字符串?的使用技巧和注意事项,需要的朋友参考一下 要检查数组中的任何字符串是否在另一个字符串中,可以使用any函数。  示例 输出结果 这将为您提供输出: 示例 尽管有些夸张,但您也可以使用正则表达式来匹配数组。例如: 输出结果 这将为您提供输出: