Как объединить «похожие» элементы во вложенном списке? - PullRequest
1 голос
/ 28 февраля 2020

У меня есть 3 вложенные списки:

STEP = [['S', '1', 'B', '3'], ['S', '3', 'B', '11'], ['S', '5', 'B', '12'], ['S', '4', 'B', '13'], ['S', '2', 'B', '14']]

TRANSITION = [['T', '2', 'B', '4'], ['T', '7', 'B', '4'], ['T', '3', 'S', '4'], ['T', '5', 'S', '5'], ['T', '1', 'S', '2'], ['T', '8', 'S', '2'], ['T', '6', 'S', '1'], ['T', '9', 'S', '2'], ['T', '4', 'S', '1'], ['T', '10', 'S', '1']]

BRANCH = [['B', '3', 'T', '1'], ['B', '3', 'T', '7'], ['B', '4', 'S', '3'], ['B', '11', 'T', '3'], ['B', '11', 'T', '5'], ['B', '12', 'T', '6'], ['B', '12', 'T', '8'], ['B', '13', 'T', '4'], ['B', '13', 'T', '9'], ['B', '14', 'T', '2'], ['B', '14', 'T', '10']]

Каждый элемент содержит информацию в таком виде:

# Example

STEP[0]  =  ['S', '1', 'B', '3']

Где:

  • 'S' - это STEP тип
  • '1' - это STEP номер ID
  • 'B' - это связанный BRANCH тип
  • «3» - это связанный BRANCH номер идентификатора

Начиная с STEP все данные связаны, поэтому, используя связанную ссылку, вы можете найти следующий элемент и следующий до другого STEP достигнуто

Вот некоторые параметры данных:

  • STEPS подключены к одному BRANCHES
  • BRANCHES подключены к одному или нескольким TRANSITIONS
  • TRANSITIONS могут быть подключены к одному BRANCH или STEP

Данные BRANCH могут иметь вилку, в которой один BRANCH id имеет одну или несколько опций для TRANSITIONS.

Я хотел бы объединить эти вилки с одним и тем же идентификатором `BRANCH ', ie:

# BRANCH[0] and BRANCH[1] both have an id of '3' 
# therefore, need to be combined

BRANCH[0] = ['B', '3', 'T', ['1', '7']] 

Это должно сделать, чтобы создать новый список, который объединяет все «как» BRANCHES.

Моя попытка до сих пор (не очень далеко):

    for i in B:
        if i[1] == B['all except current i'][1]
            # append the branch id and the two transitions

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Я почти уверен, что есть более простые способы, но на основе вашего примера вы можете попробовать:

BRANCH = [['B', '3', 'T', '1'], ['B', '3', 'T', '7'], ['B', '4', 'S', '3'], ['B', '11', 'T', '3'], ['B', '11', 'T', '5'], ['B', '12', 'T', '6'], ['B', '12', 'T', '8'], ['B', '13', 'T', '4'], ['B', '13', 'T', '9'], ['B', '14', 'T', '2'], ['B', '14', 'T', '10']]
tmp = {}
final = []
for x in BRANCH:
    if not f"{x[0]}-{x[1]}" in tmp:
        tmp[f"{x[0]}-{x[1]}"] = [x[3]]
    else:
        tmp[f"{x[0]}-{x[1]}"].append(x[3])

for k, v in tmp.items():
    one, two = k.split("-")
    for x in BRANCH:
        if x[0] == one and x[1] == two:
            if not [one, two, x[2], v] in final:
                final.append([one, two, x[2], v])

print(final)

[['B', '3', 'T', ['1', '7']], ['B', '4', 'S', ['3']], ['B', '11', 'T', ['3', '5']], ['B', '12', 'T', ['6', '8']], ['B', '13', 'T', ['4', '9']], ['B', '14', 'T', ['2', '10']]]

Демо

0 голосов
/ 28 февраля 2020

Вы можете использовать тест на сходство ветвей, а затем l oop поверх ветвей, проверяющих сходство. Остальное просто защищает от дубликатов и массирует данные в список списков. Я произвел рандомизацию данных и добавил еще один элемент, чтобы убедиться, что он не захлебнется более чем парой похожих ветвей.

# Check similarity (first three fields equal).
def similar_p(one, two):
    for item in range(len(one) - 1):
        if one[item] != two[item]:
            return False
    return True

# Data.  Works sorted and not.
branches = [
    ['B', '14', 'T', '2'],
    ['B', '12', 'T', '6'],
    ['B', '14', 'T', '10'],
    ['B', '13', 'T', '4'],
    ['B', '3', 'T', '9'],
    ['B', '12', 'T', '8'],
    ['B', '13', 'T', '9'],
    ['B', '3', 'T', '7'],
    ['B', '4', 'S', '3'],
    ['B', '11', 'T', '5'],
    ['B', '3', 'T', '1'],
    ['B', '11', 'T', '3'],
    ]

merge_dict = {}

# Loop over branches.  Uncomment print statements to watch the action.
for i in range(len(branches)):
    # print('check for similars to branch {}'.format(branches[i]))
    # try/except to ensure the dictionary item is actually there.
    try:
        # print(merge_dict[tuple(branches[i][0:3])])
        if branches[i][3] not in merge_dict[tuple(branches[i][0:3])]:
            merge_dict[tuple(branches[i][0:3])].append(branches[i][3])
            # print('initial appending to branch {}'.format(branches[i]))
    except (KeyError):
        merge_dict[tuple(branches[i][0:3])] = [branches[i][3]]
        # print('starting branch {}'.format(branches[i]))
    for j in range((i + 1), len(branches), 1):
        if similar_p(branches[i], branches[j]):
            if branches[j][3] not in merge_dict[tuple(branches[i][0:3])]:
                merge_dict[tuple(branches[i][0:3])].append(branches[j][3])
                # print('appending similar branch {} to branch {}'.format(branches[j], branches[i]))

merged = list()

# Massage into a list.  Sorting is on you, kid.
for k,v in merge_dict.items():
    if len(v) == 1:
        merged.append([*k, *v])
    else:
        merged.append([*k, v])

print(merged)

Вывод:

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