Это относится к моему предыдущему вопросу: Converting from nested lists to a delimited stringуборщик метода списка понимание очистки
У меня есть внешний сервис, который отправляет данные нам в формате с разделителями строк. Это списки предметов, глубиной до 3 уровней. Уровень 1 делится на '|'. Уровень 2 делится на ';' а уровень 3 делится на «,». Каждый уровень или элемент может содержать 0 или более элементов. Упрощенный пример:
a,b;c,d|e||f,g|h;;
У нас есть функция, которая преобразует это вложенные списки, которые, как она манипулирует в Python.
def dyn_to_lists(dyn):
return [[[c for c in b.split(',')] for b in a.split(';')] for a in dyn.split('|')]
Для приведенного выше примера, эта функция приводит к следующему:
>>> dyn = "a,b;c,d|e||f,g|h;;"
>>> print (dyn_to_lists(dyn))
[[['a', 'b'], ['c', 'd']], [['e']], [['']], [['f', 'g']], [['h'], [''], ['']]]
Для списков, на любом уровне, только один пункт, мы хотим, чтобы это как скаляр, а не список на 1 пункт , Для пустых списков мы хотим, чтобы они были пустой строкой. Я пришел с этой функцией, которая делает работу:
def dyn_to_min_lists(dyn):
def compress(x):
return "" if len(x) == 0 else x if len(x) != 1 else x[0]
return compress([compress([compress([item for item in mv.split(',')]) for mv in attr.split(';')]) for attr in dyn.split('|')])
С помощью этой функции и с помощью приведенного выше примера, он возвращает (* см обновление ниже):
[[['a', 'b'], ['c', 'd']], 'e', '', ['f', 'g'], ['h', '', '']]
Будучи новым для Python, я не уверен, что это лучший способ сделать это. Есть ли более чистые способы справиться с этим?
Это потенциально может иметь большое количество данных, проходящих через него, есть ли более эффективные/масштабируемые способы достижения этого?
Update
Я нашел ошибку в моей первоначальной функции компресса. Если внутренний список содержит более одного элемента, внешний список не может быть удален - это приведет к тому, что преобразование будет необратимым. Для этого, я обновил @ функции компресса в Blender быть:
def __compress(x):
if len(x) > 1:
return x
elif not x:
return ''
else:
if type(x[0]) != list:
return x[0]
else:
return x
Теперь он возвращает правильный вывод:
[[['a', 'b'], ['c', 'd']], 'e', '', [['f', 'g']], ['h', '', '']]
ваш список понятий перебирает строку несколько раз. было бы быстрее реализовать грамматический синтаксический анализатор? если вам действительно нужно обрабатывать множество данных, подобных этому. – akonsu
Спасибо @akonsu, хотел начать с чего-то, что работает, а затем работать над улучшением его оттуда. Я изучаю другие способы в Python для достижения этого. Я обновлю Q, если я получу что-нибудь лучше. –
@akonsu - любые ссылки, которые могут вам помочь? –