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

Jak zastąpić drugi i kolejny duplikat w liście słowem "Duplikat"?
Kaska1988
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 186
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:

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

FUNKCJA ZWRACA LISTĘ:

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

Napisałam taki oto kod:

Kopiuj
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?

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
1

wygląda jak zadanie domowe

pytoniarzem nie jestem, ale obstawiam, że w linijce

Kopiuj
tablica_temp = tablica_wejsciowa

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

ponadto w

Kopiuj
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.

Kaska1988
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 186
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.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
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:

Kopiuj
>>> 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))).

ledi12
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
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:

Kopiuj
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)
Kaska1988
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 186
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:

Kopiuj
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 :)

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
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']

ledi12
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
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.

Kaska1988
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 186
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!

ledi12
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0

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

Kopiuj
inp = ['Artur', 'Adam', 'Jacek', 'Artur', 'Zuza', 'Stefan', 'Zbigniew', 'Jacek']
new = ["Duplikat" if x in inp[:i] else x for i, x in enumerate(inp)]
Kaska1988
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 186
0
ledi12 napisał(a):

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

Kopiuj
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 😁

Manna5
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 667
0

Naiwnie coś takiego, testowane.

Kopiuj
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)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.