2012-03-21 25 views
5

Python Sözlükleri'ni kullanarak Maya'da yinelenen gölgelendiricileri silmenin bir yolunu bulmaya çalışıyorum.Bir sözlükte bulunan yinelenen değerleri ayıkla

Ben anahtarları olarak bir sözlüğüne tüm maya shader'lar koymak ve değer olarak karşılık gelen doku dosyasını koymak istiyorum: Burada

ne yapıyorum olduğunu. Sonra komut dosyasının sözlükten geçmesini ve aynı değeri paylaşan ve bunları bir diziye veya başka bir sözlüğe yerleştiren anahtarları bulmasını istiyorum.

duplicate_shaders_dict = {'b':somePath, 'd':differentPath } 

Ve zor kısmı olmak:

shaders_dict = {'a': somePath, 'b': somePath, 
       'c': differentPath, 'd': differentPath} 

duplicate_shaders_dict = {}` 

nasıl şimdi şuna benzer başka sözlük hazırlamaya o sözlükten çalıştırabilirsiniz:

Bu

şu anda ne var temelde Yinelenen dosyalar olduğundan, komut dosyasının olmasını istiyorum, bu nedenle de çift gölgelendirici sözlüğüne doldurulmaz.

+3

"Orijinal anahtar" ifadesini, örneğin sizin adınızda "a" kastediyorsunuz. Sözlüklerin sipariş edilmediğini ve “orijinal anahtarın” sadece ilk karşılaşılan “anlamına gelebileceğini” belirtmek isterim. – freespace

cevap

3

Basit bir çözüm sözlüğü tersine çevirmektir. Verilen:

>>> d = {'a': 'somePath', 'b': 'somePath', 
... 'c': 'differentPath', 'd': 'differentPath'} 

Böyle bunu tersine çevirebilir:

>>> r 
{'differentPath': 'd', 'somePath': 'b'} 

Ve sen, tekrarlar da orijinal sözlük kaldırılmış olması tersine çevirirsek:

verir

>>> r = dict((v,k) for k,v in d.iteritems()) 

>>> d = dict((v,k) for k,v in r.iteritems()) 
>>> d 
{'b': 'somePath', 'd': 'differentPath'} 
+0

ve yinelenen değerler ile dict nerede? – juliomalegria

+0

Huh, o bölümü kaçırdı. Bu, "sahip olduğum şey" ile başlıyor ve "ne istediğimi" getiriyor, bu yüzden başlamak için iyi bir yer. – larsks

+0

Bu mantıklı: ama ben sadece kopyalardan kurtulmak istemiyorum, onları başka bir değişkenin içine koymam gerekiyor, böylece daha sonra onlar üzerinde hareket edip onları sahneden siliyorum –

4

yapardım pr Böyle bir şey yapmak.

>>> from collections import defaultdict 
>>> 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> 
>>> inverse_dict = defaultdict(list) 
>>> for k,v in shaders_dict.iteritems(): 
...  inverse_dict[v].append(k) 
... 
>>> inverse_dict 
defaultdict(<type 'list'>, {'differentPath': ['c', 'd'], 'somePath': ['a', 'b']}) 

Bu temelde her anahtar, değer çifti üzerinde döngü ve değer ile ilişkili bir listeye anahtarı ekleyerek sözlüğü tersine çevirir: Birincisi, ters sözlüğü olun.

>>> first_shaders_dict = {} 
>>> duplicate_shaders_dict = {} 
>>> for v, ks in inverse_dict.iteritems(): 
...  first, rest = ks[0], ks[1:] 
...  first_shaders_dict[first] = v 
...  for r in rest: 
...   duplicate_shaders_dict[r] = v 
... 
>>> first_shaders_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_shaders_dict 
{'b': 'somePath', 'd': 'differentPath'} 

Hmm:

O zaman bu bölün. Bu, doku dosyalarının yıkanabilir olduğunu ve dolayısıyla sözlük tuşları olarak kullanılabileceğini varsayar. Öyle değilse, o zaman etrafta çalışmak zorunda kalırdım. Ayrıca, @freespace notları burada sipariş vermediğinden, belirli bir siparişi isterseniz sıralanan anahtarlar veya benzerleri üzerinde yineleme yapmak zorunda kalacağız.

-

Güncelleme: Yukarıda pek beğenmedim. Daha kısa itertools tabanlı sürüm:

>>> import itertools 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> keys = sorted(sorted(shaders_dict),key=shaders_dict.get) 
>>> by_val = [(v, list(ks)) for v, ks in itertools.groupby(keys, shaders_dict.get)] 
>>> first_dict = dict((ks[0],v) for v,ks in by_val) 
>>> duplicate_dict = dict((k,v) for v,ks in by_val for k in ks[1:]) 
>>> first_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_dict 
{'b': 'somePath', 'd': 'differentPath'} 
+0

Bunu yaptı! her ne kadar bana "büyülü" olsa da. Bu çözümü inceleyeceğim. Güncelleme için –

+0

+1 ... –

İlgili konular