operator — Operadores estándar como funciones

Código fuente: Lib/operator.py


El módulo operator exporta un conjunto de funciones eficientes correspondientes a los operadores intrínsecos de Python. Por ejemplo, operator.add(x, y) es equivalente a la expresión x+y. Muchos nombres de función son los utilizados para métodos especiales, sin los dobles guiones bajos. Por compatibilidad con versiones anteriores, muchos de estos tienen una variante que conserva los dobles guiones bajos . Se prefieren las variantes sin los dobles guiones bajos para mayor claridad.

Las funciones se dividen en categorías que realizan comparaciones de objetos, operaciones lógicas, operaciones matemáticas y operaciones sobre secuencias.

Las funciones de comparación de objetos son útiles para todos los objetos, y llevan el nombre de los operadores de comparación enriquecida que soportan:

operator.lt(a, b)
operator.le(a, b)
operator.eq(a, b)
operator.ne(a, b)
operator.ge(a, b)
operator.gt(a, b)
operator.__lt__(a, b)
operator.__le__(a, b)
operator.__eq__(a, b)
operator.__ne__(a, b)
operator.__ge__(a, b)
operator.__gt__(a, b)

Realiza «comparaciones enriquecidas» entre a y b. Específicamente, lt(a, b) es equivalente a a < b, le(a, b) es equivalente a a <= b, eq(a, b) es equivalente a a == b, ne(a, b) es equivalente a a != b, gt(a, b) es equivalente a a > b y ge(a, b) es equivalente a a >= b. Tenga en cuenta que estas funciones pueden retornar cualquier valor, que puede o no ser interpretable como un valor booleano. Consulte Comparaciones para obtener más información sobre las comparaciones enriquecidas.

Las operaciones lógicas también son aplicables a todos los objetos, y admiten pruebas de verdad, pruebas de identidad y operaciones booleanas:

operator.not_(obj)
operator.__not__(obj)

Retorna el resultado de not obj. (Tenga en cuenta que no hay ningún método __not__() para las instancias de objeto; solo el núcleo del intérprete define esta operación. El resultado se ve afectado por los métodos __bool__() y __len__().)

operator.truth(obj)

Retorna True si obj es verdadero, y False de lo contrario. Esto equivale a usar el constructor bool.

operator.is_(a, b)

Retorna a is b. Chequea la identidad del objeto.

operator.is_not(a, b)

Retorna a is not b. Chequea la identidad del objeto.

Las operaciones matemáticas y a nivel de bits son las más numerosas:

operator.abs(obj)
operator.__abs__(obj)

Retorna el valor absoluto de obj.

operator.add(a, b)
operator.__add__(a, b)

Retorna a + b, para los números a y b.

operator.and_(a, b)
operator.__and__(a, b)

Retorna la «conjunción bit a bit» (bitwise and) de a y b.

operator.floordiv(a, b)
operator.__floordiv__(a, b)

Retorna a // b.

operator.index(a)
operator.__index__(a)

Retorna a convertido a un número entero. Equivalente a a.__index__().

operator.inv(obj)
operator.invert(obj)
operator.__inv__(obj)
operator.__invert__(obj)

Retorna el «inverso bit a bit» (bitwise inverse) del número obj. Esto es equivalente a ~obj.

operator.lshift(a, b)
operator.__lshift__(a, b)

Retorna a desplazado a izquierda (shift left) b bits.

operator.mod(a, b)
operator.__mod__(a, b)

Retorna a % b.

operator.mul(a, b)
operator.__mul__(a, b)

Retorna a * b, para los números a y b.

operator.matmul(a, b)
operator.__matmul__(a, b)

Retorna a @ b.

Nuevo en la versión 3.5.

operator.neg(obj)
operator.__neg__(obj)

Retorna obj negado (-obj).

operator.or_(a, b)
operator.__or__(a, b)

Retorna la «disyunción bit a bit» (bitwise or) de a y b.

operator.pos(obj)
operator.__pos__(obj)

Retorna obj positivo (+obj).

operator.pow(a, b)
operator.__pow__(a, b)

Retorna a ** b, para los números a y b.

operator.rshift(a, b)
operator.__rshift__(a, b)

Retorna a desplazado a derecha (shift right) b bits.

operator.sub(a, b)
operator.__sub__(a, b)

Retorna a - b.

operator.truediv(a, b)
operator.__truediv__(a, b)

Retorna a / b donde 2/3 es .66 en lugar de 0. Esto también se conoce como división «real» (true division).

operator.xor(a, b)
operator.__xor__(a, b)

Retorna la disyunción exclusiva bit a bit (bitwise exclusive or) de a y b.

Las operaciones que funcionan con secuencias (y algunas de ellas también con mapeos) incluyen:

operator.concat(a, b)
operator.__concat__(a, b)

Retorna a + b para las secuencias a y b.

operator.contains(a, b)
operator.__contains__(a, b)

Retorna el resultado del chequeo b in a. Notar que los operandos se invirtieron.

operator.countOf(a, b)

Retorna el número de ocurrencias de b en a.

operator.delitem(a, b)
operator.__delitem__(a, b)

Remueve el valor de a en el índice b.

operator.getitem(a, b)
operator.__getitem__(a, b)

Retorna el valor de a en el índice b.

operator.indexOf(a, b)

Retorna el índice de la primera ocurrencia de b en a.

operator.setitem(a, b, c)
operator.__setitem__(a, b, c)

Establece el valor de a en el índice b a c.

operator.length_hint(obj, default=0)

Retorna un largo estimativo del objeto o. Primero intenta retornar su largo real, luego un estimativo usando object.__length_hint__(), y finalmente retorna un valor predeterminado.

Nuevo en la versión 3.4.

El módulo operator también define herramientas para la obtención generalizada de atributos e ítems. Estas herramientas son útiles para utilizar rápidamente extractores de campos como argumentos de map(), sorted(), itertools.groupby(), u otras funciones que esperan una función como argumento.

operator.attrgetter(attr)
operator.attrgetter(*attrs)

Retorna un objeto invocable que obtiene attr de su operando. Si se solicita más de un atributo, retorna una tupla de los atributos. Los nombres de los atributos también pueden contener puntos. Por ejemplo:

  • Después de f = attrgetter('name'), la llamada f(b) retorna b.name.

  • Después de f = attrgetter('name', 'date'), la llamada f(b)` retorna ``(b.name, b.date).

  • Después de f = attrgetter('name.first', 'name.last'), la llamada f(b) retorna (b.name.first, b.name.last).

Equivalente a:

def attrgetter(*items):
    if any(not isinstance(item, str) for item in items):
        raise TypeError('attribute name must be a string')
    if len(items) == 1:
        attr = items[0]
        def g(obj):
            return resolve_attr(obj, attr)
    else:
        def g(obj):
            return tuple(resolve_attr(obj, attr) for attr in items)
    return g

def resolve_attr(obj, attr):
    for name in attr.split("."):
        obj = getattr(obj, name)
    return obj
operator.itemgetter(item)
operator.itemgetter(*items)

Retorna un objeto invocable que obtiene item de su operando utilizando sobre el mismo el método __getitem__(). Si se especifican múltiples ítems, retorna una tupla con los valores obtenidos. Por ejemplo:

  • Después de f = itemgetter(2), la llamada f(r) retorna r[2].

  • Después de g = itemgetter(2, 5, 3), la llamada g(r) retorna (r[2], r[5], r[3]).

Equivalente a:

def itemgetter(*items):
    if len(items) == 1:
        item = items[0]
        def g(obj):
            return obj[item]
    else:
        def g(obj):
            return tuple(obj[item] for item in items)
    return g

Los ítems pueden ser de cualquier tipo aceptado por el método __getitem__() del operando. Los diccionarios aceptan cualquier valor hasheable. Las listas, las tuplas y las cadenas de caracteres aceptan un índice o un segmento:

>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1, 3, 5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2, None))('ABCDEFG')
'CDEFG'
>>> soldier = dict(rank='captain', name='dotterbart')
>>> itemgetter('rank')(soldier)
'captain'

Ejemplos que utilizan itemgetter() para obtener campos específicos de un registro tupla:

>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
>>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
operator.methodcaller(name, /, *args, **kwargs)

Retorna un objeto invocable que a su vez invoca al método name sobre su operando. Si se pasan argumentos adicionales y/o argumentos por palabra clave, estos serán a su vez pasados al método. Por ejemplo:

  • Después de f = methodcaller('name'), la llamada f(b) retorna b.name().

  • Después de f = methodcaller('name', 'foo', bar=1), la llamada f(b) retorna b.name('foo', bar=1).

Equivalente a:

def methodcaller(name, /, *args, **kwargs):
    def caller(obj):
        return getattr(obj, name)(*args, **kwargs)
    return caller

Asignación de operadores a funciones

Esta tabla muestra cómo operaciones abstractas se corresponden con operadores simbólicos en la sintaxis de Python y las funciones en el módulo operator.

Operación

Sintaxis

Función

Adición

a + b

add(a, b)

Concatenación

seq1 + seq2

concat(seq1, seq2)

Chequeo de pertenencia

obj in seq

contains(seq, obj)

División

a / b

truediv(a, b)

División

a // b

floordiv(a, b)

Conjunción lógica bit a bit (bitwise and)

a & b

and_(a, b)

Disyunción lógica bit a bit (bitwise exclusive or)

a ^ b

xor(a, b)

Inversión bit a bit (bitwise inversion)

~ a

invert(a)

Disyunción lógica bit a bit (bitwise or)

a | b

or_(a, b)

Exponenciación

a ** b

pow(a, b)

Identidad

a is b

is_(a, b)

Identidad

a is not b

is_not(a, b)

Asignación indexada

obj[k] = v

setitem(obj, k, v)

Eliminación indexada

del obj[k]

delitem(obj, k)

Indexado

obj[k]

getitem(obj, k)

Desplazamiento a izquierda (left shift)

a << b

lshift(a, b)

Módulo

a % b

mod(a, b)

Multiplicación

a * b

mul(a, b)

Multiplicación de matrices

a @ b

matmul(a, b)

Negación (aritmética)

- a

neg(a)

Negación (lógica)

not a

not_(a)

Positivo

+ a

pos(a)

Desplazamiento a derecha (right shift)

a >> b

rshift(a, b)

Asignación por segmento

seq[i:j] = values

setitem(seq, slice(i, j), values)

Eliminación por segmento

del seq[i:j]

delitem(seq, slice(i, j))

Segmentación

seq[i:j]

getitem(seq, slice(i, j))

Formateo de cadenas

s % obj

mod(s, obj)

Sustracción

a - b

sub(a, b)

Chequeo de verdad

obj

truth(obj)

Ordenado

a < b

lt(a, b)

Ordenado

a <= b

le(a, b)

Igualdad

a == b

eq(a, b)

Diferencia

a != b

ne(a, b)

Ordenado

a >= b

ge(a, b)

Ordenado

a > b

gt(a, b)

Operadores In-place

Muchas operaciones tienen una versión «in-place». Abajo se listan las funciones que proveen un acceso más primitivo a operadores in-place que la sintaxis usual; por ejemplo, el statement x += y es equivalente a x = operator.iadd(x, y). Otra forma de decirlo es que z = operator.iadd(x, y) es equivalente a la sentencia (statement) compuesta z = x; z += y.

En esos ejemplo, notar que cuando se invoca un método in-place, el cómputo y la asignación se realizan en dos pasos separados. Las funciones in-place que se listan aquí debajo solo hacen el primer paso, llamar al método in-place. El segundo paso, la asignación, no se gestiona.

Para objetivos inmutables como cadenas de caracteres, números, y tuplas, el valor actualizado es computado, pero no es asignado de nuevo a la variable de entrada:

>>> a = 'hello'
>>> iadd(a, ' world')
'hello world'
>>> a
'hello'

Para objetivos mutables como listas y diccionarios, el método in-place realiza la actualización, así que no es necesaria una asignación subsiguiente:

>>> s = ['h', 'e', 'l', 'l', 'o']
>>> iadd(s, [' ', 'w', 'o', 'r', 'l', 'd'])
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> s
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
operator.iadd(a, b)
operator.__iadd__(a, b)

a = iadd(a, b) es equivalente a a += b.

operator.iand(a, b)
operator.__iand__(a, b)

a = iand(a, b) es equivalente a a &= b.

operator.iconcat(a, b)
operator.__iconcat__(a, b)

a = iconcat(a, b) es equivalente a a += b para dos a y b secuencias.

operator.ifloordiv(a, b)
operator.__ifloordiv__(a, b)

a = ifloordiv(a, b) es equivalente a a //= b.

operator.ilshift(a, b)
operator.__ilshift__(a, b)

a = ilshift(a, b) es equivalente a a <<= b.

operator.imod(a, b)
operator.__imod__(a, b)

a = imod(a, b) es equivalente a a %= b.

operator.imul(a, b)
operator.__imul__(a, b)

a = imul(a, b) es equivalente a a *= b.

operator.imatmul(a, b)
operator.__imatmul__(a, b)

a = imul(a, b) es equivalente a a *= b.

Nuevo en la versión 3.5.

operator.ior(a, b)
operator.__ior__(a, b)

a = ior(a, b) es equivalente a a |= b.

operator.ipow(a, b)
operator.__ipow__(a, b)

a = ipow(a, b) es equivalente a a **= b.

operator.irshift(a, b)
operator.__irshift__(a, b)

a = irshift(a, b) es equivalente a a >>= b.

operator.isub(a, b)
operator.__isub__(a, b)

a = isub(a, b) es equivalente a a -= b.

operator.itruediv(a, b)
operator.__itruediv__(a, b)

a = itruediv(a, b) es equivalente a a /= b.

operator.ixor(a, b)
operator.__ixor__(a, b)

a = ixor(a, b) es equivalente a a ^= b.