2010-10-14 12 views
53

he encontrado, que no tiene que ver con la pregunta, acerca de cómo encontrar si existe al menos un elemento de una lista:
How to check if one of the following items is in a list?¿Cómo verificar si todos los siguientes elementos están en una lista?

Pero, ¿qué es lo mejor y Pythonic manera de encontrar si todos los elementos existe en una lista?

Buscando a través de los documentos que encontré esta solución:

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

Otra solución sería la siguiente:

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

Pero aquí hay que hacer más a escribir.

¿Hay alguna otra solución?

+4

¿Qué pasa con 'set (smaller) <= set (larger)'? – eumiro

Respuesta

42

operadores como <= en Python generalmente no están evitado para significar algo significativamente diferente de "menos de o igual a ". Es inusual que la biblioteca estándar lo haga, huele a API heredada.

Utilice el método equivalente y más claramente nombrado, set.issubset. Tenga en cuenta que no necesita convertir el argumento a un conjunto; lo hará por ti si es necesario.

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

no sabía que podía pasar la lista directamente como argumento para issubset ... ¡bien! – tsimbalar

+0

Aunque estoy de acuerdo con el sentimiento, estoy bastante de acuerdo con la idea de '<=' y 'issubset' que significa lo mismo. ¿Por qué no te gusta? –

+2

@Just: Principalmente, porque no es obvio lo que '<= 'significa para un conjunto sin buscarlo en los documentos o tener un conocimiento previo de lo que significa en la teoría de conjuntos, mientras que todos saben lo que' issubset' significa automáticamente. –

49

utilizaría probablemente set de la siguiente manera:

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

o al revés:

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

Me resulta un poco más fácil de leer, pero puede ser sobre-kill. Los conjuntos son particularmente útiles para calcular la unión/intersección/diferencias entre las colecciones, pero puede no ser la mejor opción en esta situación ...

+0

En realidad, 'MySet.issubset (MyOtherSet)' y 'MySet <= MyOtherSet' son lo mismo. – Wok

+1

@wok: oh, yo no sabía eso, pero creo que la <= sintaxis es un poco confusa ya que una sintaxis similar se puede usar con listas, pero con un significado muy diferente. – tsimbalar

+2

no es tan confuso si recuerda que la inclusión define una orden parcial en cualquier conjunto de conjuntos.En realidad, es un poco confuso que '<=' tenga el significado que tiene para las secuencias: se podría esperar que signifique 'es una subsecuencia' de ordenamiento no lexicográfico. – aaronasterling

4

me gusta estos dos, ya que parece la más lógica, siendo esta última más corta y probablemente más rápido (que se muestra aquí usando nuevo conjunto de literales que eran backported a Python 2.7):

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

Qué pasa si su listas contienen duplicados como este:

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

Los juegos no contienen duplicados. Entonces, la siguiente línea devuelve True.

set(v2).issubset(v1) 

que contar para duplicados, puede utilizar el código:

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) 

Por lo tanto, la siguiente línea devuelve False.

is_subseq(v2, v1) 
Cuestiones relacionadas