Pythonic преобразование одного списка элементов в строку - PullRequest
0 голосов
/ 03 мая 2018

Мне любопытно, какая эффективная / питонная реализация была бы для преобразования одного списка элементов в строку. Я работаю с lxml API, в частности xpath, который возвращает list из Element с.

Если у меня есть следующий 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)

Я полагаю, что первое будет (тривиально) более эффективным. Является ли один или другой, или какая-то альтернатива, предпочтительным подходом в отношении читабельности и эффективности.

1 Ответ

0 голосов
/ 03 мая 2018

Поскольку одной из ваших квалификаций была производительность, давайте начнем с тестирования:

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

...