Как создать подсписки в списке на основе последовательности элементов в python3?

#python #python-3.x

Вопрос:

У меня есть набор шестнадцатеричных данных, и он помещен в список под названием hex_data. Я хочу разделить список hex_data на подсписки на основе определенной повторяющейся последовательности. Например, если » ‘F5′, ’59’, ‘9A’, ‘A5′, ’58’, ’89’ » отображается в основном списке hex_data, я хочу разделить его на 2 элемента, прежде чем последовательность начнется снова, и продолжайте делать то же самое для остальной части списка. Пожалуйста, знайте, что я очень новичок в Python и, похоже, просто не могу решить эту проблему.

Вот что у меня есть до сих пор:

    sequence_of_ele = hex_data[2:8]          #'F5', '59', '9A', 'A5', '58', '89'
   for i in range(3, len(hex_data)):        # starting from 3 so it doesn't create an empty sublist before the hex_data list starts
        if hex_data[i:i 6] == sequence_of_ele:
             hex_data = do_split(hex_data, [i-2])
   print(hex_data)
 

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

 def do_split(lst, slices):
    return [sl.tolist()for sl in np.split(lst, slices)]
 

выход:

 [['B1', '1F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C2', '2A', 'A8', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'FA'], ['A9', '9F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DF', 'FA', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C1', '18', '88', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'F6', '64', '4F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '89', '90', '0A', 'AF', 'FF', 'F3', '3F', 'FB', 'B0', '0F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DB', 'BA', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '88', '80', '0A', 'AF', 'FF', 'F3', '3F', 'F']]
 

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ:

 [
['B1', '1F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C2', '2A', 'A8', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'FA'], 
['A9', '9F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DF', 'FA', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C1', '18', '88', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'F6'], 
['64','4F', 'F5', '59', '9A', 'A5', '58', '89','9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '89', '90', '0A', 'AF', 'FF', 'F3', '3F', 'FB'],
['B0', '0F', 'F5', '59', '9A', 'A5', '58', '89','9C', 'CB', 'B6', '6D', 'DD', 'DB', 'BA', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '88', '80', '0A', 'AF', 'FF', 'F3', '3F', 'FF']
]
 

Комментарии:

1. Хорошенько подумайте о том, что произойдет, когда вы это сделаете hex_data = do_split(hex_data, [i-2]) . Какое влияние это окажет на будущие попытки проверить if hex_data[i:i 6] == sequence_of_ele: ?

2. np.split позволяет указать несколько точек разделения одновременно, верно? Итак, вы пытались написать код, чтобы определить все точки разделения, а затем использовать np.split только один раз? Что произошло, когда ты попытался это сделать?

3. Это отличная мысль, Карл! Я определенно не думал об этом, так как предполагал, что код распознает его по мере повторения списка. Спасибо. Я также попробую этот подход.

Ответ №1:

Ваш код разделяет входные данные один раз, оставляя подсписк, который должен быть разделен снова с помощью той же процедуры. Таким образом, вы можете преобразовать свой код в рекурсивную функцию, т. Е. Заставить ее вызывать саму себя для обработки оставшегося подсписка.

 hex_data = ['B1', '1F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C2', '2A', 'A8', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'FA', 'A9', '9F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DF', 'FA', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C1', '18', '88', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'F6', '64', '4F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '89', '90', '0A', 'AF', 'FF', 'F3', '3F', 'FB', 'B0', '0F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DB', 'BA', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '88', '80', '0A', 'AF', 'FF', 'F3', '3F', 'FF']
sequence_of_ele = hex_data[2:8] # 'F5', '59', '9A', 'A5', '58', '89'

def do_split(lst):
    for i in range(3, len(lst)):
        if lst[i:i 6] == sequence_of_ele:
            return [lst[:i-2]]   do_split(lst[i-2:])
    return [lst]

print(do_split(hex_data))
# [
#   ['B1', '1F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C2', '2A', 'A8', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'FA'],
#   ['A9', '9F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DF', 'FA', 'A6', '66', '60', '0D', 'D3', '30', '00', '0C', 'C1', '18', '88', '8B', 'B0', '0A', 'AF', 'FF', 'F3', '3F', 'F6'],
#   ['64', '4F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'D7', '7A', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '89', '90', '0A', 'AF', 'FF', 'F3', '3F', 'FB'],
#   ['B0', '0F', 'F5', '59', '9A', 'A5', '58', '89', '9C', 'CB', 'B6', '6D', 'DD', 'DB', 'BA', 'A6', '67', '70', '0D', 'D3', '30', '00', '0C', 'C1', '1E', 'E8', '88', '80', '0A', 'AF', 'FF', 'F3', '3F', 'FF']
# ]
 

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

 output = []
bucket = [] # temporary sublist

for i, x in enumerate(hex_data):
    if hex_data[i 2:i 8] == sequence_of_ele:
        if i > 0: # don't do the following for hex_data[0]
            output.append(bucket) # flush; i.e., move bucket to output
            bucket = [] # empty the bucket
    bucket.append(x) # add the current item to the bucket
output.append(bucket) # for the last time, move bucket to output

print(output)
 

Идея состоит в том, чтобы продолжать добавлять элементы в «ведро» до тех пор, пока вы не распознаете шаблон, после чего вы перемещаете ведро в выходной список и готовите новое ведро.

Комментарии:

1. Это сработало! Большое вам спасибо за то, что объяснили мне это. Как новый программист, я все еще работаю над тем, чтобы придумать различные способы решения таких проблем.