Jak zastąpić drugi i kolejny duplikat w liście słowem "Duplikat"?

0

Cześć wszystkim!

Mam kod funkcji, która w argumencie dostaje listę z pewnymi elementami. Jeżeli wśród nich są zduplikowane elementy, wówczas pierwszy występujący element powinien być zachowany, natomiast gdy za drugim razem okazuje się że taki element już występuje, wówczas powinien być on zastąpiony słowem "DUPLIKAT". Ogólnie całość powinna wyglądać tak:
LISTA WEJŚCIOWA:

['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']

FUNKCJA ZWRACA LISTĘ:

['Artur', 'Adam', 'Jacek', 'DUPLIKAT', 'Zuza', 'Stefan', 'Zbigniew', 'DUPLIKAT']

Napisałam taki oto kod:

def pokazDuplikaty(tablica_wejsciowa):
    tablica_temp = tablica_wejsciowa
    duplikaty = 0 #licznik duplikatów

    for i in range(len(tablica_wejsciowa)):
        for j in range(len(tablica_temp)):
            if tablica_wejsciowa[i] == tablica_temp[j]:
                duplikaty += 1
            if duplikaty >= 2:
                tablica_wejsciowa[i] = "DUPLIKAT"
                duplikaty = 0
            break
    return tablica_wejsciowa

Jednak nie działa on tak jak należy. Podejrzewam, że pogubiłam się gdzieś w pętlach. Możecie pomóc?

1

wygląda jak zadanie domowe

pytoniarzem nie jestem, ale obstawiam, że w linijce

tablica_temp = tablica_wejsciowa

trzeba sklonować tablicę. potem trzeba modyfikować tą sklonowaną i na koniec ją zwrócić.

ponadto w

for j in range(len(tablica_temp)):

raczej trzeba iterować po range(i) (czyli wcześniejszych elementach) niż po całej tablicy.

cały algorytm ma złożoność kwadratową, czyli kiepską. dałoby się poprawić stosując dodatkowy zbiór z już widzianymi elementami.

ogólnie to bym cały algorytm wyrzucił do kosza i napisał nowy, ale nie będę rozwiązywać całego zadania.

0

wygląda jak zadanie domowe

Cóż, medytacja Ci nie idzie ale dzięki za pochlebstwo - szkołę i studia skończyłam dawno temu, python i programowanie to moje hobby po godzinach a kod jest częścią mojego domowego projektu.

trzeba sklonować tablicę. potem trzeba modyfikować tą sklonowaną i na koniec ją zwrócić.

W tym miejscu utworzyłam klon tablicy wejściowej. Rozumiem że masz na myśli to, aby przeprowadzać operację na klonie a nie na wejściowej tablicy? W sumie to racja.

ogólnie to bym cały algorytm wyrzucił do kosza i napisał nowy, ale nie będę rozwiązywać całego zadania.

Nie rozwiązuj bo nie oczekuję tego. Mimo wszystko dzięki za wskazówki.

2

W tym miejscu utworzyłam klon tablicy wejściowej. Rozumiem że masz na myśli to, aby przeprowadzać operację na klonie a nie na wejściowej tablicy? W sumie to racja.

tablica2 = tablica1 to nie klonowanie. poszukaj informacji jak sklonować obiekt w pytonie.

przykładowa sesyjka w replu pytonowym:

>>> a = {}
>>> b = a
>>> a['x'] = 5
>>> print(str(a))
{'x': 5}
>>> print(str(b))
{'x': 5}
>>> 

jak widać przypisanie b = a nie klonuje obiektu, bo potem zmiana poprzez jedną referencję (a['x'] = 5) jest widoczna poprzez drugą (print(str(b))).

2

Generalnie nie ma co komplikować.

Masz taki typ danych jak set, który używa algorytmu hashmapy i trzyma unikalne wartości. Wystarczy, że podczas iteracji będziesz sprawdzać czy wartość już istnieje. Jeśli tak to wtedy jest to duplikat. Przykładowy kod:

already_in = set()
inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']
new = []
for x in inp:
    if x in already_in:
        new.append("Duplikat")
    else:
        new.append(x)
        already_in.add(x)
0
ledi12 napisał(a):

Generalnie nie ma co komplikować.

Masz taki typ danych jak set, który używa algorytmu hashmapy i trzyma unikalne wartości. Wystarczy, że podczas iteracji będziesz sprawdzać czy wartość już istnieje. Jeśli tak to wtedy jest to duplikat. Przykładowy kod:

already_in = set()
inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']
new = []
for x in inp:
    if x in already_in:
        new.append("Duplikat")
    else:
        new.append(x)
        already_in.add(x)

Dzięki za info, ale czytałam o "set", natomiast zależy mi na tym aby pierwsza wartość która ma duplikaty pozostala, natomiast pozostałe zostały zamienione na słowo "DUPLIKAT". Natomiast wydaje mi się, że można to rozwiązać stosując zmienną boolean która zmienia status gdy wartość powtarza się więcej niż jeden raz podczas iteracji. Sprawdzę później :)

0
ledi12 napisał(a):

Dziwne, ale okej :D

myślę, że się nie dogadaliście i pierwszy kod od @ledi12 jest poprawny. powinien zadziałać dobrze dla przykładu z pierwszego posta:

LISTA WEJŚCIOWA:
['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']

FUNKCJA ZWRACA LISTĘ:
['Artur', 'Adam', 'Jacek', 'DUPLIKAT', 'Zuza', 'Stefan', 'Zbigniew', 'DUPLIKAT']

0
Kaska1988 napisał(a):

Dzięki za info, ale czytałam o "set", natomiast zależy mi na tym aby pierwsza wartość która ma duplikaty pozostala, natomiast pozostałe zostały zamienione na słowo "DUPLIKAT". Natomiast wydaje mi się, że można to rozwiązać stosując zmienną boolean która zmienia status gdy wartość powtarza się więcej niż jeden raz podczas iteracji. Sprawdzę później :)

Można co nie znaczy, że jest to optymalne.

0

Dzieki @ledi12 , bardzo mi pomogłeś :) Aczkolwiek muszę uważnie przeanalizować sobie ten kod w wolnej chwili bo działa, ale chciałabym rozkminić "dlaczego działa" :)

PS. Fajnego masz awatara, ostatnio to mój ulubiony serial :)

Pozdrawiam!

0

Jeszcze w sumie jest krótsza i optymalniejsza wersja :D

inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']
new = ["Duplikat" if x in inp[:i] else x for i, x in enumerate(inp)]
0
ledi12 napisał(a):

Jeszcze w sumie jest krótsza i optymalniejsza wersja :D

inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']
new = ["Duplikat" if x in inp[:i] else x for i, x in enumerate(inp)]

Już się nie popisuj 😁

0

Naiwnie coś takiego, testowane.

inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']

print (inp)

inplen = len (inp)
i = 0
while i < inplen:
        val = inp[i]
        dupl = False
        j = 0
        while j < i:
                if inp[j] == val:
                        dupl = True
                        break
                j += 1
        if dupl:
                inp[i] = "Duplikat"
        i += 1
    
print (inp)

1 użytkowników online, w tym zalogowanych: 0, gości: 1