2011-07-27 9 views
10

Estoy tratando de comparar una cadena llamada facility con varias cadenas posibles para probar si es válida. Las cadenas válidas son:Comparar una cadena con varios elementos en Python

auth, authpriv, daemon, cron, ftp, lpr, kern, mail, news, syslog, user, uucp, local0, ... , local7 

¿Hay una manera eficiente de hacerlo que no sea:

if facility == "auth" or facility == "authpriv" ... 

Respuesta

24

Si, otoh, su lista de cadenas es de hecho terriblemente largo, use un conjunto:

accepted_strings = {'auth', 'authpriv', 'daemon'} 

if facility in accepted_strings: 
    do_stuff() 

Las pruebas para la contención en un conjunto es O (1) en promedio.

+0

Sí, ese sería el camino a seguir. http://wiki.python.org/moin/PythonSpeed ​​es una lectura bastante buena para cualquier persona interesada en una visión general de la eficiencia en Python. Sin embargo, no sabría el tiempo promedio para ' set() 'would you? –

+0

Gracias por este +1, aceptado – n0pe

+0

Un posible inconveniente con esto es que el orden de iteración sobre ellos se vuelve impredecible, pero eso es solo un problema si los está usando para cualquier otra cosa (como imprima la lista de cadenas aceptadas en un mensaje de ayuda). – Ben

10

A menos que su lista de cadenas se pone terriblemente larga, algo como esto es probablemente mejor:

accepted_strings = ['auth', 'authpriv', 'daemon'] # etc etc 

if facility in accepted_strings: 
    do_stuff() 
+0

oh impresionante gracias. ¿Qué pasa si mi lista realmente es realmente larga? – n0pe

+0

Eso fue solo una pequeña broma, ya que no querría escribir una lista de 10,000 cuerdas a mano. –

+0

Esta es la opción que utilicé originalmente, pero como mi aplicación podría crecer, voy a aceptar la respuesta de @ pillmucher. Gracias +1 – n0pe

2

Para comprobar de manera eficiente si una cadena coincide con una de muchas, utilice esto:

allowed = set(('a', 'b', 'c')) 
if foo in allowed: 
    bar() 

set() s son colecciones de elementos hash, desordenadas, optimizadas para determinar si un elemento dado está en ellas.

+0

Si le preocupa la velocidad, es un poco más rápido ensamblar una tupla que una lista para iterar y crear el conjunto. – agf

+0

¿Por qué 'set()' no acepta * args (lo intenté)? :( –

+0

No tengo idea de por qué. Mi especialidad es la manipulación del código byte CPython. –

Cuestiones relacionadas