有时您必须使用列表理解将所有内容转换为字符串,包括字符串本身.
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 Truebut 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.1110201120027341Using 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.
更多推荐
如果值已经是字符串,我应该避免转换为字符串吗?
发布评论