问题描述
有时您必须使用列表理解将所有内容转换为字符串,包括字符串本身.
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 中,无需担心这种边缘情况.
因为对此有一些讨论:
- 当
isinstance(s, str)
具有不同的含义.由于子类被str()
处理成与任何其他类型的对象完全一样(在对象上调用__str__
或__repr__
),这种差异在这里很重要.您应该使用
>>>导入时间>>>timeit.timeit("type(s) is str", "s = ''")0.10074466899823165>>>timeit.timeit("type(s) == str", "s = ''")0.1110201120027341type(s) is str
进行精确的类型检查.类型是单例,利用这一点,is
更快:使用
>>>导入时间>>>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.12032335300318664s if type(s) is str else str(s)
对于非字符串情况来说,速度要慢得多:(
s = ''
案例的时间非常接近并不断交换位置).
s
可以是 str
的 子类时,本文中的所有计时都是在 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 whens
can be a subclass ofstr
. As subclasses are treated exactly like any other type of object bystr()
(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.
这篇关于如果值已经是字符串,我应该避免转换为字符串吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!