2010-10-14 13 views
53

ho trovato, che non è legato domanda, su come trovare se almeno un elemento esiste in un elenco:
How to check if one of the following items is in a list?Come verificare se tutti gli elementi seguenti sono in un elenco?

Ma qual è il modo migliore e divinatorio per trovare se tutti gli elementi esiste in un elenco?

Ricerca attraverso la documentazione ho trovato questa soluzione:

>>> l = ['a', 'b', 'c'] 
>>> set(['a', 'b']) <= set(l) 
True 
>>> set(['a', 'x']) <= set(l) 
False 

Altro soluzione potrebbe essere questa:

>>> l = ['a', 'b', 'c'] 
>>> all(x in l for x in ['a', 'b']) 
True 
>>> all(x in l for x in ['a', 'x']) 
False 

Ma qui si deve fare di più a scrivere.

Esistono altre soluzioni?

+4

Cosa c'è che non va con 'set (smaller) <= set (larger)'? – eumiro

risposta

42

Gli operatori come <= in Python non sono generalmente sovrascritti per significare qualcosa di significativamente diverso da "meno di o uguale a ". È insolito che la libreria standard lo faccia, mi sa di API legacy.

Utilizzare il metodo equivalente e più chiaramente denominato, set.issubset. Si noti che non è necessario convertire l'argomento in un set; lo farà per te, se necessario.

set(['a', 'b']).issubset(['a', 'b', 'c']) 
+2

non sapevo di poter passare la lista direttamente come argomento per issubset ... bello! – tsimbalar

+0

Mentre sono d'accordo con il sentimento, sono abbastanza OK con l'idea di '<=' e 'issubset' che significa la stessa cosa. Perché non ti piace? –

+2

@Just: Principalmente, perché non è ovvio cosa '<=' significhi per un set senza cercarlo nei documenti o avere una conoscenza preliminare di ciò che significa in teoria degli insiemi, mentre tutti sanno che cosa significa "issubset" automaticamente. –

49

avrei probabilmente usare set nel seguente modo:

set(l).issuperset(set(['a','b'])) 

o viceversa:

set(['a','b']).issubset(set(l)) 

lo trovo un po 'più leggibile, ma può essere over-kill. Gli insiemi sono particolarmente utili per calcolare l'unione/intersezione/differenze tra le raccolte, ma potrebbe non essere l'opzione migliore in questa situazione ...

+0

In realtà, "MySet.issubset (MyOtherSet)" e "MySet <= MyOtherSet' sono gli stessi. – Wok

+1

@wok: oh non lo sapevo, ma penso che la sintassi <= sia un po 'confusa in quanto una sintassi simile può essere usata con le liste, ma con un significato molto diverso. – tsimbalar

+2

non è davvero così confuso se si richiama l'inclusione definisce un ordine parziale su qualsiasi set di insiemi.In realtà è un po 'confuso che '<=' abbia il significato che ha per le sequenze: ci si potrebbe aspettare che significhi' è una successione 'piuttosto che un ordinamento lessicografico. – aaronasterling

4

Mi piace questi due perché sembrano la più logica, quest'ultimo è più corto e probabilmente più veloce (mostrato qui utilizzando il nuovo set letterali che erano backported a Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b']) 
# or 
{'a', 'b'}.issubset({'a', 'b', 'c'}) 
1

Cosa fare se la gli elenchi contengono duplicati come questo:

v1 = ['s', 'h', 'e', 'e', 'p'] 
v2 = ['s', 's', 'h'] 

Gli insiemi non contengono duplicati. Quindi, la seguente riga restituisce True.

set(v2).issubset(v1) 

Per contare i duplicati, è possibile utilizzare il codice:

v1 = sorted(v1) 
v2 = sorted(v2) 


def is_subseq(v2, v1): 
    """Check whether v2 is a subsequence of v1.""" 
    it = iter(v1) 
    return all(c in it for c in v2) 

Così, la seguente riga restituisce False.

is_subseq(v2, v1) 
Problemi correlati