Python

2010-11-12 8 views
12

ile nesne listesindeki kopyaları kaldırın Nesnelerin bir listesini aldım ve kayıtlarla dolu bir db tablosum var. Nesneler listemin bir title özniteliği var ve listeden yinelenen başlıkları olan nesneleri kaldırmak istiyorum (orijinali bırakarak).Python

Daha sonra, nesneler listemin veritabanındaki herhangi bir kaydın kopyaları olup olmadığını kontrol etmek istiyorum ve eğer varsa, bu öğeleri veritabanına eklemeden önce listeden kaldırın.

Aşağıdaki gibi bir listeden kopyaları kaldırmak için çözümler gördüm: myList = list(set(myList)), ancak bunu bir nesne listesiyle nasıl yapacağınızdan emin değilim?

Nesneler listem sırasını da korumalıyım. Ayrıca başlıklardaki farklılıkları kontrol etmek için difflib kullanabilirdim.

+4

Adım 1. arayın. Bu tam ifade, Python programlama sınıfındaki her sömestrde kullanılır. Lütfen ara. –

+0

__Orjinali mi, ne anlama geliyor? çünkü listenin order_adı sırasını değiştirmek istediğinizi söylemişseniz, listede yinelenen bir nesnenin ilk oluşumu orijinal haktır? – mouad

+0

Evet, sadece orijinal hariç tüm çoğaltmaları kaldırmak istedim. @ S.Lott, bir ton arama yaptım ve hiçbir şey bulamadım, bu yüzden buraya geldim. Bu kesin sorunu ele alan bir örnek gösterebilir misiniz? Onu gördüğüme sevinirim. – imns

cevap

28

set(list_of_objects) sadece çiftleri kaldıracaktır ki, bir nesnenin bir özgünlük tanımlamak gerekir olduğunu.

Bunu yapmak için nesneyi yıkanabilir hale getirmeniz gerekir.

http://docs.python.org/glossary.html#term-hashable

rağmen, büyük olasılıkla yalnızca __eq__ yöntemi tanımlamak gerekir: Burada nasıl, hem __hash__ ve __eq__ yöntemi tanımlamak gerekir.

DÜZENLEME: __eq__ yöntemi nasıl uygulanır?

Ben Nesnenizin benzersizliği tanımını belirtildiği gibi Biliyorsun gerekir

. Paylaşılan bir albümümüz var. Yazarın ismi ve birleşiminin benzersiz olduğu bir başlık var. (Stephen King'in yazdığı pek çok kitap ve The Shining adında bir çok kitap yazabiliriz, ama sadece bir kitap The Shining by Stephen King), sonra uygulama aşağıdaki gibidir: Benzer

def __eq__(self, other): 
    return self.author_name==other.author_name\ 
      and self.title==other.title 

, bu bazen __hash__ yöntemi uygulamak nasıl:

def __hash__(self): 
    return hash(('title', self.title, 
       'author_name', self.author_name)) 

kontrol edebilirsiniz o aynı yazar ve başlık, kitap ile 2 kitap listesi oluşturursanız nesneler ile aynı olacaktır (is operatörüyle) ve eşit (== operatörüyle). Ayrıca, set() kullanıldığında, bir kitap kaldıracaktır.

DÜZENLEME: Bu benimkilerden biri eski anwser, ama ancak şimdi son paragrafta çizili olarak düzeltilir hata olduğunu fark: is ile karşılaştırıldığında True vermeyecektir aynı hash() nesneleri . Bununla birlikte, nesneyi, setin öğeleri olarak veya sözlükte anahtar olarak kullanmayı düşünüyorsanız, nesnenin kullanılabilirliği kullanılır.

+0

Nice, '__hash__' ve' __eq__' hakkında birşey bilmiyordum. __eq__' nasıl uygulanacağına dair herhangi bir örnek var mı? – imns

+0

yukarıdaki düzenlemeye bakın – vonPetrushev

6

Bunlar yıkanabilir olmadığından, doğrudan bir set kullanamazsınız. Başlıklar olsa olmalı.

İşte ilk kısım.

seen_titles = set() 
new_list = [] 
for obj in myList: 
    if obj.title not in seen_titles: 
     new_list.append(obj) 
     seen_titles.add(obj.title) 

İkinci parça için kullandığınız hangi veritabanı/ORM'yi vs. tanımlamanız gerekecek.

+0

sqlobject ile mysql kullanıyorum. – imns

+0

10 @bababa, diğer kişilerin de görmesi için lütfen sorunu güncelleyin. – aaronasterling

+0

@bababa, sqlobject kullanarak bunu yapmanın iyi bir yolunu görmüyorum (yani, her bir nesneyi bir sorguda DB'den her nesne çekmeden veya nesne başına bir sorgulama yapmadan), böylece bir süre bekleyeceğim ve sonra birisi sqlobject’i daha iyi bilmiyorum. – aaronasterling

1

Bu oldukça az görünüyor: yinelenen bir ne olduğunu biliyorsanız

new_dict = dict() 
for obj in myList: 
    if obj.title not in new_dict: 
     new_dict[obj.title] = obj 
0

Onun oldukça kolay freinds: -

a = [5,6,7,32,32,32,32,32,32,32,32]

bir = listesi (seti (a))

baskı (a)

[5,6,7,32] 

thats it! Eğer korumak istiyorsanız :)

+5

Yukarıdakileri nesneler içeren bir listede gerçekleştiremezsiniz. –

0

orijinal sipariş kullanmak:

seen = {} 
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen] 

Kullanmaya sonra sipariş umursamıyorsan:

new_list = list(set(my_list))