2009-10-24 16 views
42

Son zamanlarda, bir setin sadece tek bir eleman içermesi durumunda, o öğe ile bir şeyler yapmak istediğim bir senaryo ile karşılaştım.Üye python'da tek üyeli kümeden nasıl çıkarılır?

element = list(myset)[0] 

Ama gereksiz bir liste oluşturur olarak bu, çok tatmin edici değildir: elemanı almak için, bu yaklaşım yerleşti. Yineleme ile de yapılabilir, ancak yineleme sadece doğal olmayan bir şey olduğu için de doğal değildir. Basit bir şey mi eksik?

cevap

62

Tuple paket açma işleri.

(element,) = myset 

(Bu arada, piton-dev araştırdı ama myset.get eklenmesini reddetmiştir() kümesinden keyfi elemanı döndürmek için. Discussion here, Guido van Rossum 1 ve 2 cevap verir.)

keyfi elemanı almak için benim kişisel favorim (bilinmeyen bir numarası var, ama sadece bir tane varsa da çalışır iken):

element = next(iter(myset)) ¹ 

: Python 2.5 ve befor E, sen iter(myset).next()

+6

Çok güzel! Eğer eleman sayısı 1 değilse, bu başarısız olur. –

+0

@Laurence: Bu iyi bir gözlem. Hataları erken yakala, doğru mu? – u0b34a0f6ae

+2

Ya da Python'un iş için uygun bir işleve sahip olduğunu iddia etmek istiyorsanız (iş arkadaşlarınız senden nefret edecekler): 'element, = myset' – rdb

2

biraz daha verimlidir veya element = tuple(myset)[0] kullanabilirsiniz kullanmak zorunda, sen

element = iter(myset).next() 

Bir yineleyici tuple/listesi hazırlarken daha etkilidir inşa tahmin gibi bir şey yapabilirsiniz . bir demet yapma ve bir yineleyici yapma Arasında

+0

Neden yineleyici oluşturmak daha verimli oluyor? –

+0

neyse, seni Alex'in yanıtına işaret ediyorum :) –

17

, bu ... burun farkıyla neredeyse bir yıkama, ancak yineleme kazanır var: bütün cevaplar daha eski sözdizimi iter(x).next() değil, kullandığınız niçin emin

$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]' 
1000000 loops, best of 3: 0.465 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]' 
1000000 loops, best of 3: 0.465 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.456 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.456 usec per loop 

Değil Bana göre tercih edilen yeni bir next(iter(x)) (ve aynı zamanda Python 3.1'de çalışır).

Ancak, her iki üzerinde açma kazanır eller aşağı:

$ python2.6 -mtimeit -s'x=set([1])' 'a,=x' 
10000000 loops, best of 3: 0.174 usec per loop 
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x' 
10000000 loops, best of 3: 0.174 usec per loop 

Bu tabii diğerleri de belirtildiği gibi, başarısız avantajına sahiptir, (tek maddelik setleri için nereye ikinci şeklidir hızlı eğer seti "biliyordum" aslında sadece bir öğe vardı birkaç tane vardı). keyfi N> 1 öğelerle setleri için, tuple iter değil, yavaşlar: tekil vaka için açma, Yani

$ python2.6 -mtimeit -s'x=set(range(99))' 'a=next(iter(x))' 
1000000 loops, best of 3: 0.417 usec per loop 
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=tuple(x)[0]' 
100000 loops, best of 3: 3.12 usec per loop 

ve genel durum için next(iter(x)), iyi görünüyor.

+0

Neden Python2.x sözdizimi? Sadece orada gerçek programlama yapıyorum ve 'python' benim sistemimde Python 2.5 ve bu yüzden bir python konsolunu açmak için tuş bağımıma bastığımda ortaya çıkan şey. – u0b34a0f6ae

+0

2.6, "gerçek programlama" için mükemmel ve 2,5'ten daha zengin; Harici ortamınız sizi sınırlandırırsa (App Engine, Civilization 4, vb) 2.5 ile yapmanın tek nedeni. sonraki (x) ve x.next() her ikisi de 2.6'da çalışır, ancak sonraki (x) daha iyidir (StopIteration istisnalarını yakalamak yerine bir varsayılan değer belirtmenize izin verir, bir tane daha az karakter gerektirir; ;-). –

+0

@Alex: Beni ikna etmeye gerek yok, python'u kullanmayı çok isterim 2.6. Debian kullanıyorum, debian henüz Python 2.6'ya geçmeyi bitirmedi! (Pyhthon 2.6'nın kendisi mevcuttur, ancak 3. bölüm kitaplıklarının hiçbiri bulunmamaktadır.) – u0b34a0f6ae

11

kaizer.se's answer'un harika olduğunu düşünüyorum. Ancak, kümeniz öğesinin birden fazla öğe içerebiliyorsa ve çok rastgele bir öğe istiyorsanız, min veya max'u kullanabilirsiniz. Örn .:

element = min(myset) 

ya:

element = max(myset) 

(bu kullanım için gereksiz yüke sahiptir çünkü, sorted kullanmayın.)

2

Önerim:

element = myset.pop() 
+0

Bu, bazı durumlarda işe yarayabilir, ancak kümeyi değiştirir. – recursive