2011-06-06 27 views
15

me gustaría realizar lo siguiente:Python: min (Ninguno, x)

a=max(a,3) 
b=min(b,3) 

Sin embargo a veces a y b puede ser None.
yo estaba feliz de descubrir que en el caso de max que funciona muy bien, dando mi resultado requerido 3, sin embargo, si es bNone, b queda None ...

Cualquiera puede pensar en un pequeño truco elegante para hacer min devuelve el número en caso de que uno de los argumentos en Ninguno?

+6

No hace lo correcto. Da el resultado esperado en uno de dos casos porque la comparación sin sentido entre 'NoneType' y' int' devuelve un valor fijo independientemente del valor entero. En Python 3, obtienes un 'TypeError' cuando haces cosas como esa (comparando tipos que no tienen un orden significativo). – delnan

+2

Parece una incoherencia en Python, más que cualquier otra cosa. –

+5

http://stackoverflow.com/questions/2214194/is-everything-greater-than-none –

Respuesta

20

¿Por qué no acaba de crear un generador de valores sin ninguna? Es más simple y más limpio.

>>> l=[None ,3] 
>>> min(i for i in l if i is not None) 
3 
+3

No hay necesidad de la comprensión de la lista. Todavía +1 (de antemano - en serio, por favor elimine los corchetes), es una solución limpia y simple. – delnan

+0

Gracias, sin llaves, ¿Python lo interpreta como una expresión de generador? – utdemir

+2

Sí. Los parens alrededor de las expresiones del generador son opcionales si el genexpr es el único argumento para una llamada a función. – delnan

3
def max_none(a, b): 
    if a is None: 
     a = float('-inf') 
    if b is None: 
     b = float('-inf') 
    return max(a, b) 

def min_none(a, b): 
    if a is None: 
     a = float('inf') 
    if b is None: 
     b = float('inf') 
    return min(a, b) 

max_none(None, 3) 
max_none(3, None) 
min_none(None, 3) 
min_none(3, None) 
+0

Tenga en cuenta que esto solo funciona si el valor predeterminado es 0. Pasar 0 en lugar de 'None' todavía se activa cuando pasa el valor predeterminado pero no lo hace cambie el valor ya que el valor predeterminado es 0 (y '0 == 0.0 == 0j'). – delnan

+1

El OP dijo que max no era un problema. ¿Qué sucede si b es negativo? –

+0

Respuesta modificada. –

2

Puede utilizar una línea if y una infinidad como predeterminado, ya que esto funcionará para cualquier valor:

a = max(a if a is not None else float('-inf'), 3) 
b = min(b if b is not None else float('inf'), 3) 
+0

'a = 0' rompe esto. – delnan

+0

Está bien, entonces lo haré un poco más explícito – Blender

+0

Entonces esto pasará 'Verdadero' en ocasiones;) – delnan

3

Aquí es un decorador de línea que se puede utilizar para filtrar los valores Ninguno que podrían ser pasados ​​a una función:

noNones = lambda fn : lambda *args : fn(a for a in args if a is not None) 
print noNones(min)(None, 3) 
print noNones(max)(None, 3) 

impresiones:

3 
3 
0
a=max(a,3) if a is not None else 3 
b=min(b,3) if b is not None else 3 
0

@ de utdemir La respuesta funciona muy bien para el ejemplo proporcionado, pero generaría un error en algunos escenarios.

Una cuestión que surge es si tiene una lista con solo None valores. Si proporciona una secuencia vacía a min(), se generará un error:

>>> mylist = [None, None] 
>>> min(value for value in mylist if value) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: min() arg is an empty sequence 

Como tal, este fragmento impediría el error:

def find_minimum(minimums): 
    potential_mins = (value for value in minimums if value is not None) 
    if potential_mins: 
     return min(potential_mins) 
1

Una solución para el Python 3

Código:

# variable lst es su secuencia

min(filter(lambda x: x is not None, lst)) if any(lst) else None 

Ejemplos:

In [3]: lst = [None, 1, None] 

In [4]: min(filter(lambda x: x is not None, lst)) if any(lst) else None 
Out[4]: 1 

In [5]: lst = [-4, None, 11] 

In [6]: min(filter(lambda x: x is not None, lst)) if any(lst) else None 
Out[6]: -4 

In [7]: lst = [0, 7, -79] 

In [8]: min(filter(lambda x: x is not None, lst)) if any(lst) else None 
Out[8]: -79 

In [9]: lst = [None, None, None] 

In [10]: min(filter(lambda x: x is not None, lst)) if any(lst) else None 

In [11]: print(min(filter(lambda x: x is not None, lst)) if any(lst) else None) 
None 

Notas:

Trabaja en la secuencia se presenta como números, así como Ninguno.Si todos los valores son Ninguno min() excepción aumento

ValueError: min() arg is an empty sequence

Este código de resolver este problema en todos los

Pros:

  1. funcionado si Ninguno presenta en secuencia
  2. trabajado en Python 3
  3. max() también funcionará

Contras

Necesita una variable (ejemplo LST) o necesitan duplicar la secuencia