Самый быстрый способ конвертировать строку в список кортежей - PullRequest
0 голосов
/ 28 октября 2019

У меня есть миллионы строк вида

"[(0, 1, 2), (3, 4, 5), (6, 7, 8)...]"

, которые мне нужно преобразовать в списки Python, содержащие кортежи. Я обнаружил eval (что плохо и медленно) и ast.literal_eval, что немного быстрее, но я ищу что-то немного быстрее, если оно существует. К сожалению, использование json.loads не работает для меня, так как строки не являются технически допустимыми JSON из-за скобок.

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

json.loads() не может понимать кортежи, но может понимать массивы []. Я не знаю, что это оптимальный метод, но может быть использован для решения проблемы.

Хитрость здесь в том, чтобы заменить ( на [ и ) на ].

import json

data = "[(1,2,3),(4,5,6)]"

data = data.replace("(", "[")
data = data.replace(")", "]")

data = json.loads(data)

tuple_list = []
for t in data :
  tuple_list.append(tuple(t))

print(tuple_list)
0 голосов
/ 28 октября 2019

Я не знаю, насколько точен магический метод ipython timeit, но следующий результат кажется достаточно хорошим:

In [28]: s = "[(0, 1, 2), (3, 4, 5), (6, 7, 8)]"

In [29]: %timeit l = eval(s)
100000 loops, best of 3: 12.4 µs per loop

In [30]: %timeit l = ast.literal_eval(s)
10000 loops, best of 3: 21.2 µs per loop

In [31]: %timeit l = [tuple(x) for x in json.loads(s.replace('(', '[').replace(')', ']'))]
The slowest run took 6.04 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.8 µs per loop
...