Как переименовать повторяющиеся элементы в списке списков python на основе вертикального положения? - PullRequest
2 голосов
/ 25 февраля 2020

У меня есть список списков, подобных этому:

listofLists = [
                ['a', 'b', 'e'],
                ['a', 'd'],
                ['a', 'c'],
                ['a', 'b', 'c', 'e'],
                ['a', 'e', 'c', 'f']
                ]

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

Например, первая позиция 'e' находится в индексе 1 в списке ['a', 'e', ​​'c', 'f'] должно остаться как есть. Следующая позиция 'e' находится в индексе 2 в списке ['a', 'b', 'e'], который должен быть переименован в 'e1'. Последняя позиция 'e' находится в списке ['a', 'b', 'c', 'e'], который должен быть переименован в 'e3'

Требуемый вывод должен быть:

requiredOutput = [['a', 'b', 'e1'],
                  ['a', 'd'],
                  ['a', 'c'],
                  ['a', 'b', 'c1', 'e2'],
                  ['a', 'e', 'c1', 'f']]

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

transformedListOfTuples = list(zip_longest(*listofLists))
transformedListOfList= [list(x) for x in transformedListOfTuples]
for i in range(0, len(listofLists)):
    for j in range(0, len(listofLists[i])):
        pos = -1
        for z in range(0, len(transformedListOfList)):
            if listofLists[i][j] in transformedListOfList[z]:
                pos = pos + 1
                if pos == 0:
                    continue
                elif pos > 0:
                    listofLists[i][j] = listofLists[i][j] + str(pos)
            elif listofLists[i][j] not in transformedListOfList[z]:
                continue

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Как насчет этого:

arr = [
    ['a', 'b', 'e'],
    ['a', 'd'],
    ['a', 'c'],
    ['a', 'b', 'c', 'e'],
    ['a', 'e', 'c', 'f']
]

listOfRepeated = []
max_len = 0

for i in range(0, len(arr)):
    if max_len < len(arr[i]):
        max_len = len(arr[i])

for j in range(0, max_len):
    list_to_add = []
    for i in range(0, len(arr)):
        if j < len(arr[i]):
            val = arr[i][j]
            # For each iteration of `i`, you'll go down the group

            if not val in list_to_add:
                list_to_add.append(val)

            count = listOfRepeated.count(val)
            if count > 0:
                arr[i][j] = ""+str(val)+""+str(count)

    for element in list_to_add:
        listOfRepeated.append(element)

for list in arr:
    print(list)

Вывод:

['a', 'b', 'e1']
['a', 'd']
['a', 'c']
['a', 'b', 'c1', 'e2']
['a', 'e', 'c1', 'f']

Объяснение:

j - это счетчик go по горизонтали, i счетчик go вниз по группе. Каждый элемент присутствует в arr[i][j]

list_to_add - это список, который содержит каждый уникальный символ для определенной группы

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

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

вы можете использовать:

previous = {}
for i in range(max(len(e) for e in listofLists)):
    col = [l[i] for l in listofLists if len(l) > i]
    previous.update({e: previous.get(e, 0) + 1 for e in set(col)})

    for l in listofLists:
        if len(l) > i:
            if previous[l[i]] > 1:
                l[i] = l[i] + str(previous[l[i]] - 1)
listofLists

вывод:

[['a', 'b', 'e1'],
 ['a', 'd'],
 ['a', 'c'],
 ['a', 'b', 'c1', 'e2'],
 ['a', 'e', 'c1', 'f']]

как это работает: previous dict будет хранить текущее число вхождений элемента в столбцах, первое for l oop итерация по всем столбцам, на каждом шаге итерации previous диктует, что она обновляется на основе элементов из текущего столбца, внутренний for l oop обновляет каждый элемент из текущего столбца если число вхождений в столбцах превышает 1

или вы можете использовать:

from itertools import accumulate, zip_longest
from collections import Counter

cols = list(zip_longest(*listofLists))
t = [[f'{e}{a[e] - 1}' if e and a[e] > 1 else e for e in i] for i, a in
     zip(cols, accumulate((Counter(set(l)) for l in cols)))]
listofLists = [[e[i] for e in t if e[i]] for i in range(len(t[0]))]

, вы работаете с каждым столбцом и получаете транспонирование желаемого результата (это t)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...