将单个项目列表Pythonic转换为字符串

RJ7*_*RJ7 0 python performance lxml

我很好奇将单个项目列表转换为字符串的高效/Pythonic 实现是什么。我正在使用lxmlapi,特别xpath是它返回 a listof Elements。

假设我有以下 xml

<Root>
  <Name>MyName</Name>
  <Comment>MyComment</Comment>
  <Details>
    <Value>1</Value>
  </Details>
</Root>
Run Code Online (Sandbox Code Playgroud)

现在我想检索 的值a = xpath('Comment/text()')(假设上下文节点是Root)。我可以使用以下之一。

strExample = a[0] 
Run Code Online (Sandbox Code Playgroud)

或者

strExample = ''.join(a)
Run Code Online (Sandbox Code Playgroud)

我认为前者会(稍微)更有效率。就可读性和效率而言,其中之一或某种替代方法是首选方法。

aba*_*ert 5

由于您的资格之一是表现,让我们首先测试一下:

\n\n
In [314]: %timeit a[0]\n39.4 ns \xc2\xb1 1.38 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000000 loops each)    \nIn [315]: %timeit ''.join(a)\n81 ns \xc2\xb1 3.68 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000000 loops each)\nIn [316]: a = ['My Comment' * 100000]    \nIn [317]: %timeit a[0]\n39.2 ns \xc2\xb1 0.696 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000000 loops each)\nIn [318]: %timeit ''.join(a)\n81.4 ns \xc2\xb1 2.79 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,作为粗略的猜测,a[0]速度大约是两倍,并且这是一个恒定的差异,而不取决于字符串的长度。

\n\n

当然,如果您考虑一下,这可能''.join(a)是 CPython 特定的或 CPython 3.6 特定的 \xe2\x80\xa6 的东西,虽然有可能在没有对单个值进行某些优化的情况下是线性的,但很难想象这a[0]可能是。

\n\n
\n\n

接下来,哪个更具可读性?好吧,从概念上讲,您要做的就是从列表中获取第一个也是唯一一个值。

\n\n
    \n
  • a[0]从列表中获取第一个值,这在只有一个值的假设下显然是相同的。
  • \n
  • ''.join(a)从列表中获取所有值,并将其连接在一起。假设只有一个并且它是一个字符串,您可以很容易地证明它是同一件事,但它并不是那么明显。
  • \n
\n\n
\n\n

另一个潜在的问题是稳健性。

\n\n

未找到该元素,a因此该元素为空,这似乎是一种合理的可能性。在这种情况下,a[0]将引发一个IndexError,而''.join(a)将默默返回一个空字符串。

\n\n

发现多个元素似乎是永远不应该发生的事情。如果确实如此,a[0]将返回第一个,这可能仍然有用,同时''.join(a)会默默地将它们全部连接在一起成为废话,这几乎肯定不会。(尽管如果这种情况可能发生,并且您的代码没有准备好处理它,那么您最好添加显式if len(a) != 1: raise SomeException(\xe2\x80\xa6)测试,而不是依赖其中任何一个。)

\n\n
\n\n

将所有这些放在一起,我认为a[0]这是一种显而易见的方法(除非您需要针对多个值的鲁棒性,在这种情况下进行显式测试,然后a[0]是 TOOWTDI)。

\n