🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
4 messages
4 total messages Started by grryf Wed, 07 Oct 2009 13:09
Usuwanie duplikatów
#26860
Author: grryf
Date: Wed, 07 Oct 2009 13:09
84 lines
3290 bytes
Proszę dodajcie swoje 3 grosze:

# CEL: USUN POPRZEDNIE WERSJE:
# Algorytm:
# 1. skataloguj wszystkie pliki w podkatalogach, zapisz [nazwa,
sciezka, rozmiar, modyfikacja]
# 2. Posortuj wg nazwy i rozmiaru
# 3. Sprawdz kolejne pliki, jezeli nazwa i rozmiar sa takie same jak
nastepnego pliku to usun ktorys

# Czas ostatniej modyfikacji #os.stat(path).st_mtime

# Znane bledy: program trzeba wykonac 2-3 razy bo za kazdym razem
jeszcze cos znajduje (duzo duplikatow jeden za drugim)

import os
pliki = []


# 1:
sciezka = r"d:\My Documents\Downloads\Music_mp3"

def find_dupl(sciezka):
    from os.path import join
    for root, dirs, files in os.walk(sciezka):
        for name in files:
            pliki.append([name, root+'\\'+name, os.stat(root+'\
\'+name).st_size, os.stat(root+'\\'+name).st_mtime])
    print "Skatalogowano plikow:", len(pliki)

find_dupl(sciezka)


# 2:
# Wlasna funkcja sortujaca ktora sortuje po dwoch parametrach
def multisort(x,y):
    nazwa = 0
    sciezka = 1
    rozmiar = 2
    data_modyf = 3
    if x[nazwa] > y[nazwa]:
        return 1
    elif x[nazwa] < y[nazwa]:
        return -1
    else:
        if x[rozmiar] > y[rozmiar]:
            return 1
        elif x[rozmiar] < y[rozmiar]:
            return -1
        else:
            return 0

# Sortowanie przy uzyciu wlasnej funkcji sortujacej
pliki.sort(multisort)


# 3:
def usun_dupl(pliki):
    nazwa = 0
    sciezka = 1
    rozmiar = 2
    data_modyf = 3
    poprzedni = pliki[0]
    ile = 0
    for plik in pliki[1:]:
        if poprzedni == None:
            poprzedni = plik
            continue
        if plik[nazwa] == poprzedni[nazwa] and plik[rozmiar] ==
poprzedni[rozmiar]:
            if plik[data_modyf] > poprzedni[data_modyf]:
                os.remove(poprzedni[sciezka])
                ile+=1
            elif plik[data_modyf] < poprzedni[data_modyf]:
                os.remove(plik[sciezka])
                ile+=1
                plik = None
            else:
                os.remove(poprzedni[sciezka])
                ile+=1
        poprzedni = plik
    print "Usunieto plikow:",ile

usun_dupl(pliki)
Re: Usuwanie duplikatów
#26861
Author: Bart Ogryczak
Date: Wed, 07 Oct 2009 14:02
109 lines
4679 bytes
On Oct 7, 3:09 pm, grryf <rade...@gmail.com> wrote:
> Proszę dodajcie swoje 3 grosze:
>
> # CEL: USUN POPRZEDNIE WERSJE:
> # Algorytm:
> # 1. skataloguj wszystkie pliki w podkatalogach, zapisz [nazwa,
> sciezka, rozmiar, modyfikacja]
> # 2. Posortuj wg nazwy i rozmiaru
> # 3. Sprawdz kolejne pliki, jezeli nazwa i rozmiar sa takie same jak
> nastepnego pliku to usun ktorys
>
> # Czas ostatniej modyfikacji #os.stat(path).st_mtime
>
> # Znane bledy: program trzeba wykonac 2-3 razy bo za kazdym razem
> jeszcze cos znajduje (duzo duplikatow jeden za drugim)
>
> import os
> pliki = []
>
> # 1:
> sciezka = r"d:\My Documents\Downloads\Music_mp3"
>
> def find_dupl(sciezka):
>     from os.path import join
>     for root, dirs, files in os.walk(sciezka):
>         for name in files:
>             pliki.append([name, root+'\\'+name, os.stat(root+'\
> \'+name).st_size, os.stat(root+'\\'+name).st_mtime])
>     print "Skatalogowano plikow:", len(pliki)


def find_dupl(sciezka)  #nieco nie pasuje nazwa
   for root, dirs, files in os.walk(sciezka):
   pliki.extend([(name, join(root,name), os.stat( join
(root,name)).st_size,os.stat(join(root,name)).st_mtime) for name in
files])

I tak nie tędy droga... ale o tym zaraz...

> # 2:
> # Wlasna funkcja sortujaca ktora sortuje po dwoch parametrach
> def multisort(x,y):

Nie ma potrzeby, zwykłe sortowanie robi to automatycznie.
pliki.sort()

> # Sortowanie przy uzyciu wlasnej funkcji sortujacej
> pliki.sort(multisort)
>
> # 3:
> def usun_dupl(pliki):
>     nazwa = 0
>     sciezka = 1
>     rozmiar = 2
>     data_modyf = 3
>     poprzedni = pliki[0]
>     ile = 0
>     for plik in pliki[1:]:
>         if poprzedni == None:
>             poprzedni = plik
>             continue
>         if plik[nazwa] == poprzedni[nazwa] and plik[rozmiar] ==
> poprzedni[rozmiar]:
>             if plik[data_modyf] > poprzedni[data_modyf]:
>                 os.remove(poprzedni[sciezka])
>                 ile+=1
>             elif plik[data_modyf] < poprzedni[data_modyf]:
>                 os.remove(plik[sciezka])
>                 ile+=1
>                 plik = None
>             else:
>                 os.remove(poprzedni[sciezka])
>                 ile+=1
>         poprzedni = plik
>     print "Usunieto plikow:",ile
>
> usun_dupl(pliki)

łał...

Ok, a tak od zera:


from os.path import join

def slownik_duplikatow(sciezka):
    duplikaty = {}
    for root, dirs, files in os.walk(sciezka):
       for name in files:
          stat = os.stat(join(root,name))
          duplikaty.setdefault((name, stat.st_size),[]).append
((stat.st_mtime, root))

# jaśniej...
def usun_duplikaty(slownik):
    for (name,size), lista in slownik.items():
       if len(lista)>1:
          lista.sort(reverse=true) # posortowane od najnowszego
          duplikaty_do_skasowania = lista[1:] #wszystkie z wyjątkiem
najnowszego
          for mtime, root in duplikaty_do_skasowania:
             os.remove(join(root,name))

# ... albo krócej

def usun_duplikaty(slownik):
    for (name,size), lista in slownik.items():
       for mtime, root in sorted(lista,reverse=true)[1:]:
         os.remove(join(root,name))
Re: Usuwanie duplikatów
#26862
Author: grryf
Date: Fri, 09 Oct 2009 08:40
30 lines
2125 bytes
Bardzo mi się podoba Twoje rozwiązanie! Dziękuję za uwagę.

A poniżej ten sam kod (by Bart), w pełni działający:

from os.path import join
import os

duplikaty = {}
sciezka = r"d:\My Documents\Downloads\Programs"

def slownik_duplikatow(sciezka):
    #duplikaty = {}
    for root, dirs, files in os.walk(sciezka):
       for name in files:
          stat = os.stat(join(root,name))
          duplikaty.setdefault((name, stat.st_size),[]).append
((stat.st_mtime, root))

slownik_duplikatow(sciezka)

# ... albo krócej
def usun_duplikaty(slownik):
    for (name,size), lista in slownik.items():
       for mtime, root in sorted(lista,reverse=True)[1:]:
         os.remove(join(root,name))

usun_duplikaty(duplikaty)

#Ps. co do sort'a w moim programie to aby sortowal po dwoch
argumentach to naprawde bylo trzeba napisac multisort (sprawdzalem)
Re: Usuwanie duplikatów
#26863
Author: Bart Ogryczak
Date: Fri, 09 Oct 2009 12:35
8 lines
1757 bytes
On Oct 9, 10:40 am, grryf <rade...@gmail.com> wrote:

> #Ps. co do sort'a w moim programie to aby sortowal po dwoch
> argumentach to naprawde bylo trzeba napisac multisort (sprawdzalem)

Zapewne wystarczyło zmienić kolejność, tak żeby te dwa pola po których
sortowałeś były na początku (tak jak miałeś, sortowałeś po polu
pierwszym i trzecim).
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads