单项列表到字符串的 Pythonic 转换
Pythonic conversion of single item list to string
我很好奇 efficient/pythonic 将单个项目列表转换为字符串的实现方式。我正在使用 lxml
api,特别是 xpath
其中 returns list
of Element
s.
假设我有以下 xml
<Root>
<Name>MyName</Name>
<Comment>MyComment</Comment>
<Details>
<Value>1</Value>
</Details>
</Root>
现在我想检索 a = xpath('Comment/text()')
的值(假设上下文节点是 Root
)。我可以使用以下之一。
strExample = a[0]
或
strExample = ''.join(a)
我认为前者会(平凡地)更有效率。就可读性和效率而言,一种或另一种或某种替代方法是首选方法。
由于您的资格之一是性能,让我们从测试开始:
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)
将静默 return 一个空字符串。
发现多个元素似乎是不应该发生的事情。如果是这样,a[0]
将 return 第一个,这可能仍然有用,而 ''.join(a)
将默默地将它们全部加入废话,这几乎肯定不会。 (尽管如果 可能 发生,并且您的代码没有准备好处理它,您最好添加一个明确的 if len(a) != 1: raise SomeException(…)
测试而不是依赖任何一个。)
综上所述,我认为 a[0]
是一种显而易见的方法(除非您需要针对多个值的稳健性,在这种情况下进行显式测试,然后 a[0]
,是 TOOWTDI).
我很好奇 efficient/pythonic 将单个项目列表转换为字符串的实现方式。我正在使用 lxml
api,特别是 xpath
其中 returns list
of Element
s.
假设我有以下 xml
<Root>
<Name>MyName</Name>
<Comment>MyComment</Comment>
<Details>
<Value>1</Value>
</Details>
</Root>
现在我想检索 a = xpath('Comment/text()')
的值(假设上下文节点是 Root
)。我可以使用以下之一。
strExample = a[0]
或
strExample = ''.join(a)
我认为前者会(平凡地)更有效率。就可读性和效率而言,一种或另一种或某种替代方法是首选方法。
由于您的资格之一是性能,让我们从测试开始:
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)
将静默 return 一个空字符串。
发现多个元素似乎是不应该发生的事情。如果是这样,a[0]
将 return 第一个,这可能仍然有用,而 ''.join(a)
将默默地将它们全部加入废话,这几乎肯定不会。 (尽管如果 可能 发生,并且您的代码没有准备好处理它,您最好添加一个明确的 if len(a) != 1: raise SomeException(…)
测试而不是依赖任何一个。)
综上所述,我认为 a[0]
是一种显而易见的方法(除非您需要针对多个值的稳健性,在这种情况下进行显式测试,然后 a[0]
,是 TOOWTDI).