переформатировать элементы в списках в разные типы и подсписки - PullRequest
0 голосов
/ 29 октября 2018
UNCLEANED = [
['1 -  32/', 'Highway', '403', '43.167233',
 '-80.275567', '1965', '2014', '2009', '4',
 'Total=64  (1)=12;(2)=19;(3)=21;(4)=12;', '65', '04/13/2012', '72.3', '',
 '72.3', '', '69.5', '', '70', '', '70.3', '', '70.5', '', '70.7', '72.9',
 ''],
['1 -  43/', 'WEST', '403', '43.164531', '-80.251582',
 '1963', '2014', '2007', '4',
 'Total=60.4  (1)=12.2;(2)=18;(3)=18;(4)=12.2;', '61', '04/13/2012',
 '71.5', '', '71.5', '', '68.1', '', '69', '', '69.4', '', '69.4', '',
 '70.3', '73.3', ''],
['2 -   4/', 'STOKES', '6', '45.036739', '-81.33579', '1958',
 '2013', '', '1', 'Total=16  (1)=16;', '18.4', '08/28/2013', '85.1',
 '85.1', '', '67.8', '', '67.4', '', '69.2', '70', '70.5', '', '75.1', '',
 '90.1', '']
]

выше - это неочищенная версия списка, содержащего три подсписка ... и мне нужно преобразовать его в более чистую версию, которая может выглядеть примерно так:

CLEANED = [[1, 'Highway', '403', 43.167233,
              -80.275567, '1965', '2014', '2009', 4,
              [12.0, 19.0, 21.0, 12.0], 65.0, '04/13/2012',
              [72.3, 69.5, 70.0, 70.3, 70.5, 70.7, 72.9]],
             [2, 'WEST', '403', 43.164531, -80.251582,
              '1963', '2014', '2007', 4, [12.2, 18.0, 18.0, 12.2], 61.0, 
              '04/13/2012', [71.5, 68.1, 69.0, 69.4, 69.4, 70.3,
                             73.3]],
             [3, 'STOKES', '6', 45.036739, -81.33579, '1958',
              '2013', '', 1, [16.0], 18.4, '08/28/2013',
              [85.1, 67.8, 67.4, 69.2, 70.0, 70.5, 75.1, 90.1]]
            ]

и я понял, что шаблон для индекса [0] в неочищенной версии, я оставляю только первый символ. index[1], [2] оставьте прежним, превратите index[3] и [4] в int .....

затем достигните index[9], я должен проигнорировать итоговое значение и извлечь только оставшиеся числа, затем поместить в подсписок .....

последнее, что нужно поместить числа после даты в подсписок, а также исключить первое число.

Я очень озадачен тем, как постоянно зацикливать это, пока не закончится «очистка» всего в UNCLEANED ?

А что если UNCLEANED - это не только эти три элемента? если бы это было очень долго, как бы я прошел через это?

Большое спасибо за вашу помощь

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Вот альтернативный способ очистки списка списков с использованием набора функций.

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

Я предположил, что непустое строковое значение в первых 3 элементах хвостовой части каждого подмассива было желаемым значением. arrange обрабатывает размещение первых 3 элементов в порядке, который возвращает согласованное значение.

ИМХО, преимущество этого способа в том, что если вы хотите сделать что-то другое с каким-либо конкретным элементом, вам будет проще изменить код.

import itertools as it

def get_first_char_int(item):
    first_char, *_ = item
    return int(first_char)

def identity(item):
    return item

def get_floats(item):
    tokens = ''.join(item.split(' ')[2:]).split('=')[1:]
    return [float(token.split(';')[0]) for token in tokens]

def get_float(item):
    return float(item) if item else item

UNCLEANED = [
    ['1 -  32/', 'Highway', '403', '43.167233',
     '-80.275567', '1965', '2014', '2009', '4',
     'Total=64  (1)=12;(2)=19;(3)=21;(4)=12;', '65', '04/13/2012', '72.3', '',
     '72.3', '', '69.5', '', '70', '', '70.3', '', '70.5', '', '70.7', '72.9',
     ''],
    ['1 -  43/', 'WEST', '403', '43.164531', '-80.251582',
     '1963', '2014', '2007', '4',
     'Total=60.4  (1)=12.2;(2)=18;(3)=18;(4)=12.2;', '61', '04/13/2012',
     '71.5', '', '71.5', '', '68.1', '', '69', '', '69.4', '', '69.4', '',
     '70.3', '73.3', ''],
    ['2 -   4/', 'STOKES', '6', '45.036739', '-81.33579', '1958',
     '2013', '', '1', 'Total=16  (1)=16;', '18.4', '08/28/2013', '85.1',
     '85.1', '', '67.8', '', '67.4', '', '69.2', '70', '70.5', '', '75.1', '',
     '90.1', ''],
]

functions = [ # 1:1 mapping of functions to items in each list in UNCLEANED.
    get_first_char_int,
    identity,
    identity,
    float,
    float,
    identity,
    identity,
    identity,
    int,
    get_floats,
    float,
    identity,
]
end = len(functions)
item_length, = {len(items) for items in UNCLEANED}
# Calculate argument to pass to it.islice
extra_count = item_length - end
# Extend functions by extra_count times with get_float
functions.extend(list(it.repeat(get_float, extra_count)))
#
# Handle items up to start of alternating strings and empty strings.
head_results = (
    [f(item)
     for f, item
     in zip(functions[0:end], collection[0:end])]
    for collection in UNCLEANED
)

def arrange(items):
    """Handle varying order of first 3 items of items."""
    item, *_ = items
    items[0:3] = [item, '', item]
    return items
#
# Apply arrange to the tail of each sublist
collection_ = it.chain.from_iterable(arrange(collection[end:])
                                     for collection in UNCLEANED)
#
# Handle items starting with alternating strings and empty strings.
tail_results = (
    [f(item)
     for f, item
     in it.islice(zip(functions[end:], collection_), 2, item_length)]
    for collection in UNCLEANED
)

results = [[head, [item for item in tail if item]]
            for head, tail in zip(head_results, tail_results)]

for item in results:
    print(item)

Выход:

[[1, 'Highway', '403', 43.167233, -80.275567, '1965', '2014', '2009', 4, [12.0, 19.0, 21.0, 12.0], 65.0, '04/13/2012'], [72.3, 69.5, 70.0, 70.3, 70.5, 70.7, 72.9]]
[[1, 'WEST', '403', 43.164531, -80.251582, '1963', '2014', '2007', 4, [12.2, 18.0, 18.0, 12.2], 61.0, '04/13/2012'], [71.5, 68.1, 69.0, 69.4, 69.4, 70.3, 73.3]]
[[2, 'STOKES', '6', 45.036739, -81.33579, '1958', '2013', '', 1, [16.0], 18.4, '08/28/2013'], [85.1, 67.8, 67.4, 69.2, 70.0, 70.5, 75.1, 90.1]]
0 голосов
/ 30 октября 2018

Создайте функцию clean_row (row), тогда все «чистые правила» должны быть вызваны отсюда. Тогда вы можете сделать CLEANED = [clean_row(uncleaned) for uncleaned in UNCLEANED].

0 голосов
/ 29 октября 2018

Вот решение, которое выполняет преобразование, описанное выше. Это простой for цикл:

UNCLEANED = [
['1 -  32/', 'Highway', '403', '43.167233',
 '-80.275567', '1965', '2014', '2009', '4',
 'Total=64  (1)=12;(2)=19;(3)=21;(4)=12;', '65', '04/13/2012', '72.3', '',
 '72.3', '', '69.5', '', '70', '', '70.3', '', '70.5', '', '70.7', '72.9',
 ''],
['1 -  43/', 'WEST', '403', '43.164531', '-80.251582',
 '1963', '2014', '2007', '4',
 'Total=60.4  (1)=12.2;(2)=18;(3)=18;(4)=12.2;', '61', '04/13/2012',
 '71.5', '', '71.5', '', '68.1', '', '69', '', '69.4', '', '69.4', '',
 '70.3', '73.3', ''],
['2 -   4/', 'STOKES', '6', '45.036739', '-81.33579', '1958',
 '2013', '', '1', 'Total=16  (1)=16;', '18.4', '08/28/2013', '85.1',
 '85.1', '', '67.8', '', '67.4', '', '69.2', '70', '70.5', '', '75.1', '',
 '90.1', '']
]

# Function that performs the conversion described above.
def cleanElement(elem):
    elem[0] = elem[0].split(' - ')[0]
    elem[3] = float(elem[3])
    elem[4] = float(elem[4])

    elem[8] = int(elem[8])

    tempList = elem[9].split('  ')[1].split(';')
    tempList = [float(i.split('=')[1]) for i in tempList if not i=='']
    elem[9] = tempList

    elem[10] = float(elem[10])

    elem[13] = [float(i) for i in elem[13:] if not i=='']
    elem.pop(12)

    return elem[:13]

# Function that loops in the uncleaned list and performs the conversion for each element.
def cleanList(uncleaned):
    return [cleanElement(elem) for elem in uncleaned]

cleaned = cleanList(UNCLEANED)

for i in cleaned:
    print(i)

Выход:

['1', 'Highway', '403', 43.167233, -80.275567, '1965', '2014', '2009', 4, [12.0, 19.0, 21.0, 12.0], 65.0, '04/13/2012', [72.3, 69.5, 70.0, 70.3, 70.5, 70.7, 72.9]]
['1', 'WEST', '403', 43.164531, -80.251582, '1963', '2014', '2007', 4, [12.2, 18.0, 18.0, 12.2], 61.0, '04/13/2012', [71.5, 68.1, 69.0, 69.4, 69.4, 70.3, 73.3]]
['2', 'STOKES', '6', 45.036739, -81.33579, '1958', '2013', '', 1, [16.0], 18.4, '08/28/2013', [85.1, 67.8, 67.4, 69.2, 70.0, 70.5, 75.1, 90.1]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...