tutorial lenguaje español descargar python

python - lenguaje - ¿Cómo verificar si uno de los siguientes elementos está en una lista?



python tutorial (13)

¡Piensa en lo que dice el código en realidad!

>>> (1 or 2) 1 >>> (2 or 1) 2

Eso probablemente debería explicarlo. :) Python aparentemente implementa "perezoso o", lo que no debería ser una sorpresa. Lo realiza algo como esto:

def or(x, y): if x: return x if y: return y return False

En el primer ejemplo, x == 1 e y == 2 . En el segundo ejemplo, es viceversa. Es por eso que devuelve diferentes valores según el orden de ellos.

Estoy tratando de encontrar una forma breve de ver si alguno de los siguientes elementos está en una lista, pero mi primer intento no funciona. Además de escribir una función para lograr esto, es la forma más sencilla de verificar si uno de los múltiples elementos está en una lista.

>>> a = [2,3,4] >>> print (1 or 2) in a False >>> print (2 or 1) in a True


1 línea sin listas de comprensión.

>>> any(map(lambda each: each in [2,3,4], [1,2])) True >>> any(map(lambda each: each in [2,3,4], [1,5])) False >>> any(map(lambda each: each in [2,3,4], [2,4])) True


Ah, Tobías me lo ganaste. Estaba pensando en esta ligera variación en su solución:

>>> a = [1,2,3,4] >>> b = [2,7] >>> print(any(x in a for x in b)) True


Cuando piense "verificar si hay a en b", piense en hashes (en este caso, conjuntos). La manera más rápida es revisar la lista que desea verificar y luego verificar cada elemento allí.

Esta es la razón por la cual la respuesta de Joe Koberg es rápida: verificar la intersección establecida es muy rápido.

Sin embargo, cuando no tienes muchos datos, hacer conjuntos puede ser una pérdida de tiempo. Entonces, puedes hacer un conjunto de la lista y simplemente verificar cada ítem:

tocheck = [1,2] # items to check a = [2,3,4] # the list a = set(a) # convert to set (O(len(a))) print [i for i in tocheck if i in a] # check items (O(len(tocheck)))

Cuando la cantidad de elementos que desea verificar es pequeña, la diferencia puede ser insignificante. Pero compruebe muchos números contra una lista grande ...

pruebas:

from timeit import timeit methods = [''''''tocheck = [1,2] # items to check a = [2,3,4] # the list a = set(a) # convert to set (O(n)) [i for i in tocheck if i in a] # check items (O(m))'''''', ''''''L1 = [2,3,4] L2 = [1,2] [i for i in L1 if i in L2]'''''', ''''''S1 = set([2,3,4]) S2 = set([1,2]) S1.intersection(S2)'''''', ''''''a = [1,2] b = [2,3,4] any(x in a for x in b)''''''] for method in methods: print timeit(method, number=10000) print methods = [''''''tocheck = range(200,300) # items to check a = range(2, 10000) # the list a = set(a) # convert to set (O(n)) [i for i in tocheck if i in a] # check items (O(m))'''''', ''''''L1 = range(2, 10000) L2 = range(200,300) [i for i in L1 if i in L2]'''''', ''''''S1 = set(range(2, 10000)) S2 = set(range(200,300)) S1.intersection(S2)'''''', ''''''a = range(200,300) b = range(2, 10000) any(x in a for x in b)''''''] for method in methods: print timeit(method, number=1000)

velocidades:

M1: 0.0170331001282 # make one set M2: 0.0164539813995 # list comprehension M3: 0.0286040306091 # set intersection M4: 0.0305438041687 # any M1: 0.49850320816 # make one set M2: 25.2735087872 # list comprehension M3: 0.466138124466 # set intersection M4: 0.668627977371 # any

El método consistentemente rápido es hacer un conjunto (de la lista), ¡pero la intersección funciona mejor en grandes conjuntos de datos!


En algunos casos (por ejemplo, elementos de lista únicos), se pueden usar operaciones de conjunto.

>>> a=[2,3,4] >>> set(a) - set([2,3]) != set(a) True >>>

O bien, utilizando set.isdisjoint() ,

>>> not set(a).isdisjoint(set([2,3])) True >>> not set(a).isdisjoint(set([5,6])) False >>>


Esto lo hará en una línea.

>>> a=[2,3,4] >>> b=[1,2] >>> bool(sum(map(lambda x: x in b, a))) True


Lo mejor que se me ocurrió fue:

any([True for e in (1, 2) if e in a])


Recopilé varias de las soluciones mencionadas en otras respuestas y en comentarios, luego realicé una prueba de velocidad. not set(a).isdisjoint(b) resultó ser el más rápido, tampoco disminuyó mucho cuando el resultado fue False .

Cada una de las tres pruebas prueba una pequeña muestra de las posibles configuraciones de b . Los tiempos son en microsegundos.

Any with generator and max 2.093 1.997 7.879 Any with generator 0.907 0.692 2.337 Any with list 1.294 1.452 2.137 True in list 1.219 1.348 2.148 Set with & 1.364 1.749 1.412 Set intersection explcit set(b) 1.424 1.787 1.517 Set intersection implicit set(b) 0.964 1.298 0.976 Set isdisjoint explicit set(b) 1.062 1.094 1.241 Set isdisjoint implicit set(b) 0.622 0.621 0.753

import timeit def printtimes(t): print ''{:.3f}''.format(t/10.0), setup1 = ''a = range(10); b = range(9,15)'' setup2 = ''a = range(10); b = range(10)'' setup3 = ''a = range(10); b = range(10,20)'' print ''Any with generator and max/n/t'', printtimes(timeit.Timer(''any(x in max(a,b,key=len) for x in min(b,a,key=len))'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''any(x in max(a,b,key=len) for x in min(b,a,key=len))'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''any(x in max(a,b,key=len) for x in min(b,a,key=len))'',setup=setup3).timeit(10000000)) print print ''Any with generator/n/t'', printtimes(timeit.Timer(''any(i in a for i in b)'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''any(i in a for i in b)'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''any(i in a for i in b)'',setup=setup3).timeit(10000000)) print print ''Any with list/n/t'', printtimes(timeit.Timer(''any([i in a for i in b])'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''any([i in a for i in b])'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''any([i in a for i in b])'',setup=setup3).timeit(10000000)) print print ''True in list/n/t'', printtimes(timeit.Timer(''True in [i in a for i in b]'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''True in [i in a for i in b]'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''True in [i in a for i in b]'',setup=setup3).timeit(10000000)) print print ''Set with &/n/t'', printtimes(timeit.Timer(''bool(set(a) & set(b))'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a) & set(b))'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a) & set(b))'',setup=setup3).timeit(10000000)) print print ''Set intersection explcit set(b)/n/t'', printtimes(timeit.Timer(''bool(set(a).intersection(set(b)))'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a).intersection(set(b)))'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a).intersection(set(b)))'',setup=setup3).timeit(10000000)) print print ''Set intersection implicit set(b)/n/t'', printtimes(timeit.Timer(''bool(set(a).intersection(b))'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a).intersection(b))'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''bool(set(a).intersection(b))'',setup=setup3).timeit(10000000)) print print ''Set isdisjoint explicit set(b)/n/t'', printtimes(timeit.Timer(''not set(a).isdisjoint(set(b))'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''not set(a).isdisjoint(set(b))'',setup=setup2).timeit(10000000)) printtimes(timeit.Timer(''not set(a).isdisjoint(set(b))'',setup=setup3).timeit(10000000)) print print ''Set isdisjoint implicit set(b)/n/t'', printtimes(timeit.Timer(''not set(a).isdisjoint(b)'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''not set(a).isdisjoint(b)'',setup=setup1).timeit(10000000)) printtimes(timeit.Timer(''not set(a).isdisjoint(b)'',setup=setup3).timeit(10000000)) print


Sencillo.

_new_list = [] for item in a: if item in b: _new_list.append(item) else: pass


Tal vez un poco más flojo:

a = [1,2,3,4] b = [2,7] print any((True for x in a if x in b))


>>> L1 = [2,3,4] >>> L2 = [1,2] >>> [i for i in L1 if i in L2] [2] >>> S1 = set(L1) >>> S2 = set(L2) >>> S1.intersection(S2) set([2])

Tanto las listas vacías como los conjuntos vacíos son falsos, por lo que puede usar el valor directamente como un valor de verdad.


a = {2,3,4} if {1,2} & a: pass

Código de golf versión. Considere usar un conjunto si tiene sentido hacerlo. Encuentro esto más legible que una lista de comprensión.


print (1 in a) or (2 in a) print (2 in a) or (5 in a)

Esta es una pregunta muy antigua, pero no estaba contento con ninguna de las respuestas, así que tuve que agregar esto por el bien de la posteridad.