Python: как преобразовать строку в список, не создавая чрезмерно арочный список - PullRequest
0 голосов
/ 15 февраля 2019

Мне отправили данные в ужасном формате, состоящем из ряда точек с последующими атрибутами.Каждая точка ограничена квадратными скобками [], но в настоящее время является строковым типом.

Я пытался использовать стандартный метод list() для преобразования строки, однако при этом получается вся строка, состоящая из множества точек,в список.Я хочу использовать существующие квадратные скобки в строке для распознавания как списки, а не создавать сводный список, содержащий один элемент.

Данные в строковом типе выглядят следующим образом.Ниже приведена только одна группа точек, и у меня есть сотни, чтобы перебрать;двойные открывающие и закрывающие квадратные скобки в начале и в конце означают группу.

[[451166.32,719761.36,20.37,0.06,],[451162.97,719765.06,20.41,0.048,1],[451161.63,719766.54,10.17,0.048,],[451158.26,719770.23,20.44,0.048,],[451156.19,719772.54,20.05,0.048,0],[451148.7,719780.68,-10.77,0.048,],[451138.57,719791.95,-10.2,0.048,],[451129.33,719802.15,-10.38,0.048,],[451118.07,719814.56,10.06,0.048,],[451105.98,719827.91,-10.64,0.048,],[451095.10,719839.91,-10.47,0.048,],[451087.17,719848.66,-10.72,0.048,],[451082.94,719853.31,10.92,0.048,0],[451078.,719858.77,2.75,10.048,],[451076.79,719860.10,5.2,10.06,1]]

Я пробовал list(xsData.split(",")), [i.strip("[],").split(",") for i in myList] и несколько других методов, новсе либо помещают строку в общий список, либо помещают каждый символ в свой собственный список.

Конечная цель состоит в том, чтобы иметь возможность перебирать каждый элемент в каждом списке, чтобы записать данныев более дружественный формат, например, TXT / CSV.

Редактировать: ast.literal.eval() работает со всеми группами точек, кроме группы ниже, выдает ошибку invalid syntax.Я не вижу причины, почему.[[455972.1700000000128057,786651.7399999999906868,44.4499999999999993,0.045,],[455976.5700000000069849,786652.7800000000279397,10.2899999999999991,4.04,1],[455977.7000000000116415,786653.0500000000465661,12.8300000000000001,1.04,],[455979.0499999999883585,786653.3699999999953434,2.8800000000000008,0.04,],[455979.6900000000023283,786653.5200000000186265,3.4199999999999999,5.04,],[455983.9299999999930151,786654.5200000000186265,9.75,0.04,],[455990.8900000000139698,786656.1700000000419095,0.8499999999999996,0.04,],[455993.5100000000093132,786656.7900000000372529,0.4100000000000001,0.04,],[455993.7900000000081491,786656.8499999999767169,0.3300000000000001,0.04,],[455994.8699999999953434,786657.1099999999860302,4.5199999999999996,0.04,],[455997.0499999999883585,786657.6300000000046566,4.6100000000000003,0.04,],[455997.5899999999965075,786657.75,4.8600000000000003,0.04,],[455998.7099999999918509,786658.0200000000186265,1.0099999999999998,0.045,1],[456000.3200000000069849,786658.4000000000232831,1.3699999999999992,0.045,],[456002.2799999999988358,786658.8599999999860302,17.6400000000000006,0.045,],[456006.2900000000081491,786659.8100000000558794,14.8100000000000005,0.045,],[456009.5899999999965075,786660.5899999999674037,10.4399999999999995,,],[456017.0,786662.3499999999767169,19.1099999999999994,,]]

1 Ответ

0 голосов
/ 15 февраля 2019

Если строка выглядит как синтаксически правильный список Python, вы можете получить данные этого списка, вызвав ast.literal_eval:

>>> import ast
>>> s = "[[451166.32,719761.36,20.37,0.06,],[451162.97,719765.06,20.41,0.048,1],[451161.63,719766.54,10.17,0.048,],[451158.26,719770.23,20.44,0.048,],[451156.19,719772.54,20.05,0.048,0],[451148.7,719780.68,-10.77,0.048,],[451138.57,719791.95,-10.2,0.048,],[451129.33,719802.15,-10.38,0.048,],[451118.07,719814.56,10.06,0.048,],[451105.98,719827.91,-10.64,0.048,],[451095.10,719839.91,-10.47,0.048,],[451087.17,719848.66,-10.72,0.048,],[451082.94,719853.31,10.92,0.048,0],[451078.,719858.77,2.75,10.048,],[451076.79,719860.10,5.2,10.06,1]]"
>>> x = ast.literal_eval(s)
>>> type(x)
<class 'list'>
>>> x
[[451166.32, 719761.36, 20.37, 0.06], [451162.97, 719765.06, 20.41, 0.048, 1], [451161.63, 719766.54, 10.17, 0.048], [451158.26, 719770.23, 20.44, 0.048], [451156.19, 719772.54, 20.05, 0.048, 0], [451148.7, 719780.68, -10.77, 0.048], [451138.57, 719791.95, -10.2, 0.048], [451129.33, 719802.15, -10.38, 0.048], [451118.07, 719814.56, 10.06, 0.048], [451105.98, 719827.91, -10.64, 0.048], [451095.1, 719839.91, -10.47, 0.048], [451087.17, 719848.66, -10.72, 0.048], [451082.94, 719853.31, 10.92, 0.048, 0], [451078.0, 719858.77, 2.75, 10.048], [451076.79, 719860.1, 5.2, 10.06, 1]]

Я не совсем уверен, но похоже, что ваша строка можетна самом деле выглядит как несколько списков, объединенных вместе, и в этом случае вы не можете просто вызвать literal_eval:

>>> import ast
>>> s = "[1,2][3,4,[[5,6],7]][8,9]"
>>> ast.literal_eval(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Programming\Python 3.6\lib\ast.py", line 85, in literal_eval
    return _convert(node_or_string)
  File "C:\Programming\Python 3.6\lib\ast.py", line 84, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Subscript object at 0x02E25650>

Если это так, вы можете разделить ваши данные на отдельные группы, чтобы вы могли оценитьих независимо.

import ast

def separate_groups(s):
    """finds matching square brackets within `s` and yields successive portions that resemble valid list literals.
    note: may not operate correctly on data that contains quoted brackets, for example `"[1, '[', 2][3,4]"`
    """
    depth = 0
    last_seen_group_end = -1
    for i,c in enumerate(s):
        if c == "[":
            depth += 1
        elif c == "]":
            depth -= 1
            if depth == 0:
                yield s[last_seen_group_end+1: i+1]
                last_seen_group_end = i

s = "[1,2][3,4,[[5,6],7]][8,9]"
result = [ast.literal_eval(group) for group in separate_groups(s)]
print(result)

Результат:

[[1, 2], [3, 4, [[5, 6], 7]], [8, 9]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...