如果值已经是字符串,我应该避免转换为字符串吗? [英] Should I avoid converting to a string if a value is already a string?

查看:58
本文介绍了如果值已经是字符串,我应该避免转换为字符串吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时您必须使用列表理解将所有内容转换为字符串,包括字符串本身.

b = [str(a) for a in l]

但我必须这样做吗:

b = [a if type(a)==str else str(a) for a in l]

我想知道字符串上的 str 是否被优化到足以创建该字符串的另一个副本.

我试过了:

<预><代码>>>>x="aaaaaa">>>str(x) 是 x真的

但这可能是因为 Python 可以缓存字符串并重用它们.但是对于字符串的任何值都能保证这种行为吗?

解决方案

测试对象是否已经是字符串比总是转换为字符串要慢.

那是因为 str() 方法也进行了完全相同的测试(对象是否已经是字符串).您 a) 做了两倍的工作,b) 您的测试启动速度较慢.

注意:对于 Python 2,在 unicode 对象上使用 str() 包括对 ASCII 的隐式编码,这可能会失败.您可能仍然需要对此类对象进行特殊情况处理.在 Python 3 中,无需担心这种边缘情况.

因为对此有一些讨论:

    s 可以是 str子类时,
  • isinstance(s, str) 具有不同的含义.由于子类被 str() 处理成与任何其他类型的对象完全一样(在对象上调用 __str____repr__),这种差异在这里很重要.
  • 您应该使用 type(s) is str 进行精确的类型检查.类型是单例,利用这一点,is 更快:

    <预><代码>>>>导入时间>>>timeit.timeit("type(s) is str", "s = ''")0.10074466899823165>>>timeit.timeit("type(s) == str", "s = ''")0.1110201120027341

  • 使用 s if type(s) is str else str(s) 对于非字符串情况来说,速度要慢得多:

    <预><代码>>>>导入时间>>>timeit.timeit("str(s)", "s = None")0.1823573520014179>>>timeit.timeit("s if type(s) is str else str(s)", "s = None")0.29589492800005246>>>timeit.timeit("str(s)", "s = ''")0.11716728399915155>>>timeit.timeit("s if type(s) is str else str(s)", "s = ''")0.12032335300318664

    (s = '' 案例的时间非常接近并不断交换位置).

本文中的所有计时都是在 Macbook Pro 15"(2015 年中)、OS X 10.12.3 上使用 Python 3.6.0 进行的.

Sometimes you have to use list comprehension to convert everything to string including strings themselves.

b = [str(a) for a in l]

But do I have to do:

b = [a if type(a)==str else str(a) for a in l]

I was wondering if str on a string is optimized enough to not create another copy of the string.

I have tried:

>>> x="aaaaaa"
>>> str(x) is x
True

but that may be because Python can cache strings, and reuses them. But is that behaviour guaranteed for any value of a string?

解决方案

Testing if an object is already a string is slower than just always converting to a string.

That's because the str() method also makes the exact same test (is the object already a string). You are a) doing double the work, and b) your test is slower to boot.

Note: for Python 2, using str() on unicode objects includes an implicit encode to ASCII, and this can fail. You may still have to special case handling of such objects. In Python 3, there is no need to worry about that edge-case.

As there is some discussion around this:

  • isinstance(s, str) has a different meaning when s can be a subclass of str. As subclasses are treated exactly like any other type of object by str() (either __str__ or __repr__ is called on the object), this difference matters here.
  • You should use type(s) is str for exact type checks. Types are singletons, take advantage of this, is is faster:

    >>> import timeit
    >>> timeit.timeit("type(s) is str", "s = ''")
    0.10074466899823165
    >>> timeit.timeit("type(s) == str", "s = ''")
    0.1110201120027341
    

  • Using s if type(s) is str else str(s) is significantly slower for the non-string case:

    >>> import timeit
    >>> timeit.timeit("str(s)", "s = None")
    0.1823573520014179
    >>> timeit.timeit("s if type(s) is str else str(s)", "s = None")
    0.29589492800005246
    >>> timeit.timeit("str(s)", "s = ''")
    0.11716728399915155
    >>> timeit.timeit("s if type(s) is str else str(s)", "s = ''")
    0.12032335300318664
    

    (The timings for the s = '' cases are very close and keep swapping places).

All timings in this post were conducted on Python 3.6.0 on a Macbook Pro 15" (Mid 2015), OS X 10.12.3.

这篇关于如果值已经是字符串,我应该避免转换为字符串吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆