我应该避免转换为string,如果一个值已经是一个string?

有时你必须使用列表理解来把所有东西都转换成string,包括string本身。

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

但是我必须这样做:

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

我想知道,如果一个stringstr是足够优化, 创build另一个string的副本。

我努力了:

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

但这可能是因为Python可以cachingstring,并重新使用它们。 但是,这种行为保证了任何string的值?

testing一个对象是否已经是一个string比只是总是转换成一个string要慢。

这是因为str()方法也使得完全相同的testing(对象已经是一个string)。 你a)做了两倍的工作,b)你的testing启动较慢。

注意:对于Python 2,在unicode对象上使用str()包含对ASCII的隐式编码,这可能会失败。 您可能仍然需要特殊情况下处理这些对象。 在Python 3中,没有必要担心这种边缘情况。

正如有关这个的一些讨论:

  • s可以是str子类isinstance(s, str)具有不同的含义。 由于子类通过str() (对象上调用了__str____repr__ str()与任何其他types的对象完全相同,所以这里的区别很重要。
  • 你应该使用type(s) is str进行精确的types检查。 types是单身人士,利用这一点,是更快:

     >>> import timeit >>> 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)使用s if type(s) is str else str(s)对于非string的情况, s if type(s) is str else str(s)要慢得多:

     >>> 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 

    s = '' case”的时间非常接近并且保持交换位置)。

这篇文章中的所有时间都是在Macbook Pro 15“(2015年中)OS X 10.12.3上的Python 3.6.0上进行的。