整数是python的数据类型吗_基本数据类型(字符串和整数)是如何在Python和P中实现的...

本文探讨了Python中字符串和列表操作的时间复杂度,如连接、索引访问和切片复制。指出字符串连接操作对于大规模数据是O(n),而列表索引访问保持在O(1)。同时,介绍了Python对象的内部结构,如PyStringObject和PyListObject,揭示了它们的内存管理和性能影响。
摘要由CSDN通过智能技术生成

在python中,some_string[5] = 'a'将是一个错误,但是最接近的等效操作some_string = some_string[5:] + 'a' + some_string[6:]确实是O(n)。但这不仅仅适用于不可变对象。对于连接列表也是如此:[1,2,3] + [4,5,6]生成一个新的列表,并且是O(n)。在

加上数字会创建一个新值,但通常结果值在内存中的大小总是相同的,所以它是O(1)。当然,这只适用于小整数。一旦达到某个阈值(在我的机器上是20位数字),INT会突然占用可变的空间量。我不知道这是如何影响渐近性能的。在

然而,我发现即使在log10(n) == 1000附近,它似乎也没有明显的效果:>>> times = [timeit.timeit(stmt=stmt.format(10 ** i, 10 ** i), number=100) for i in range(1000)]

>>> sum(times) * 1.0 / len(times)

3.0851364135742186e-06

>>> times[-1]

3.0994415283203125e-06

对于字符串,渐近性能下降更为明显:

^{pr2}$

最后一个操作的执行时间远低于平均值。而且趋势相当稳定:>>> for t in times[0:100000:10000]:

... print t

...

5.00679016113e-06

1.31130218506e-05

2.90870666504e-05

3.88622283936e-05

5.10215759277e-05

6.19888305664e-05

7.41481781006e-05

8.48770141602e-05

9.60826873779e-05

0.000108957290649

不过,像这样的小规模操作还是相当便宜的。在

为了扩展您的其他问题,索引访问在列表和字符串上都是O(1)。在>>> stmt = 'x = s[{0}] + s[{1}] + s[{2}]'

>>> setup = 's = "a" * {0}'

>>> times = [timeit.timeit(stmt=stmt.format(i / 2, i / 3, i / 4), setup=setup.format(i + 1), number=10) for i in range(1000000)]

>>> sum(times) * 1.0 / len(times)

3.6441037654876707e-06

>>> times[-1]

3.0994415283203125e-06

与列表类似:>>> stmt = 'x = s[{0}] + s[{1}] + s[{2}]'

>>> setup = 's = ["a"] * {0}'

>>> times = [timeit.timeit(stmt=stmt.format(i / 2, i / 3, i / 4), setup=setup.format(i + 1), number=10) for i in range(100000)]

>>> sum(times) * 1.0 / len(times)

2.8617620468139648e-06

>>> times[-1]

1.9073486328125e-06

切片复制字符串和列表,因此与n == len(slice)一起为O(n)。没有“好”的方法来替换字符串中的一个字母,尽管我想强调的是,“坏”的方法在大多数情况下已经足够好了。如果您想要一个“好”的方法,可以使用不同的数据类型;操作一个列表,并在需要字符串时连接它;或者使用StringIO对象。This page有一些关于连接不同内置Python数据类型的有用信息。在

最后,由于您对内部结构非常感兴趣,我在^{}中挖掘了struct的PyStringObject声明(来自版本2.7;3+可能看起来不同)。它是关于你所期望的一个c字符串和一些额外的铃声和口哨:typedef struct {

PyObject_VAR_HEAD

(PyObject_VAR_HEAD是一个c预处理器宏,它根据解释的规则here展开为类似下面的内容。)Py_ssize_t ob_refcnt;

PyTypeObject *ob_type;

Py_ssize_t ob_size;

继续。。。在long ob_shash;

int ob_sstate;

char ob_sval[1];

/* Invariants:

* ob_sval contains space for 'ob_size+1' elements.

* ob_sval[ob_size] == 0.

* ob_shash is the hash of the string or -1 if not computed yet.

* ob_sstate != 0 iff the string object is in stringobject.c's

* 'interned' dictionary; in this case the two references

* from 'interned' to this object are *not counted* in ob_refcnt.

*/

} PyStringObject;

列表有一个similar structurec数组,它有额外的铃铛和哨声,但不是以null结尾的,并且通常有额外的预分配存储空间。在

不用说。。。这其中大部分只适用于cPythonPyPy,IronPython,和Jython看起来完全不同!在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值