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

时间:2018-05-03 17:47:25

标签: python performance lxml

我很好奇将单个项目列表转换为字符串的高效/ pythonic实现。我正在使用for name, df in dfs.items(): merged = df.merge(animals, on=['col']) merged.to_csv('{}.csv'.format(name)) api,特别是lxml,它会返回xpathlist个。

假设我有以下xml

Element

现在我想检索<Root> <Name>MyName</Name> <Comment>MyComment</Comment> <Details> <Value>1</Value> </Details> </Root> 的值(假设上下文节点是a = xpath('Comment/text()'))。我可以使用以下其中一种。

Root

strExample = a[0] 

我认为前者会(通常)更有效率。就可读性和效率而言,是一种或另一种或一些替代方案。

1 个答案:

答案 0 :(得分:4)

由于你的一个资格是表现,我们首先测试一下:

In [314]: %timeit a[0]
39.4 ns ± 1.38 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)    
In [315]: %timeit ''.join(a)
81 ns ± 3.68 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [316]: a = ['My Comment' * 100000]    
In [317]: %timeit a[0]
39.2 ns ± 0.696 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [318]: %timeit ''.join(a)
81.4 ns ± 2.79 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

因此,粗略猜测,a[0]的速度大约是其两倍,这是一个常数差异,不依赖于字符串的长度。

当然可能可能是CPython特有的,或CPython 3.6特定的......如果你考虑它们,而''.join(a)可能是线性的而没有一些优化单个值,很难想象a[0]可能是。

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

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

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

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

找到的多个元素似乎永远不会发生。如果确实如此,a[0]将返回第一个,这可能仍然有用,而''.join(a)将默默地将它们加入到废话中,这几乎肯定不会。 (虽然如果可能发生,并且您的代码没有准备好处理它,您可能最好添加一个明确的if len(a) != 1: raise SomeException(…)测试而不是依赖它们。)

把这一切放在一起,我认为a[0]是一种明显的做法(除非你需要对多个值的鲁棒性,在这种情况下,一个显式测试,然后是a[0],是TOOWTDI )。