tutorial lenguaje instalar descargar python

lenguaje - python wikipedia



Lista parcial desempaquetar en Python (11)

Pero a veces no sé un tamaño de la lista a la derecha, por ejemplo, si uso split ().

Sí, cuando tengo casos con límite> 1 (por lo que no puedo usar la partición) por lo general relleno para:

def paddedsplit(s, find, limit): parts= s.split(find, limit) return parts+[parts[0][:0]]*(limit+1-len(parts)) username, password, hash= paddedsplit(credentials, '':'', 2)

(las parts[0][:0] están ahí para obtener un ''str'' o ''unicode'' vacío, que coincida con cualquiera de los que se produjeron en la división. Podría usar Ninguno si lo prefiere.)

En Python, el operador de asignación puede descomprimir una lista o una tupla en variables, como esto:

l = (1, 2) a, b = l # Here goes auto unpack

Pero necesito especificar exactamente la misma cantidad de nombres a la izquierda que un recuento de elementos en la lista a la derecha. Pero a veces no sé el tamaño de la lista a la derecha, por ejemplo, si uso split ().

Ejemplo:

a, b = "length=25".split("=") # This will result in a="length" and b=25

Pero el siguiente código llevará a un error:

a, b = "DEFAULT_LENGTH".split("=") # Error, list has only one item

¿Es posible descomprimir de alguna manera la lista en el ejemplo anterior para que pueda obtener a = "DEFAULT_LENGTH" yb es igual a None o no está configurado? Un camino sencillo parece un poco largo:

a = b = None if "=" in string : a, b = string.split("=") else : a = string


¿Has probado esto?

values = aString.split("=") if len(values) == 1: a = values[0] else: a, b = values


Como alternativa, ¿quizás usar una expresión regular?

>>> import re >>> unpack_re = re.compile("(/w*)(?:=(/w*))?") >>> x = "DEFAULT_LENGTH" >>> unpack_re.match(x).groups() (''DEFAULT_LENGTH'', None) >>> y = "length=107" >>> unpack_re.match(y).groups() (''length'', ''107'')

Si se asegura de que re.match () siempre sea exitoso, .groups () siempre devolverá la cantidad correcta de elementos para desempaquetar en su tupla, para que pueda hacerlo de manera segura.

a,b = unpack_re.match(x).groups()


Esto es un poco mejor que su solución pero aún no es muy elegante; no me sorprendería si hubiera una mejor manera de hacerlo.

a, b = (string.split("=") + [None])[:2]


Esto puede no serle de utilidad a menos que esté usando Python 3. Sin embargo, para completar, vale la pena notar que el desempaquetado de tuplas extendido introducido allí le permite hacer cosas como:

>>> a, *b = "length=25".split("=") >>> a,b ("length", [''25'']) >>> a, *b = "DEFAULT_LENGTH".split("=") >>> a,b ("DEFAULT_LENGTH", [])

Es decir, el desempaquetado de la tupla ahora funciona de manera similar a como lo hace en el desempaquetado de argumentos, por lo que puede denotar "el resto de los elementos" con * , y obtenerlos como una lista (posiblemente vacía).

Sin embargo, la partición es probablemente la mejor solución para lo que estás haciendo.


La mejor manera es usar el método de cadena de partición :

Divida la cadena en la primera aparición de septiembre y devuelva una tupla 3 que contenga la parte anterior al separador, el separador mismo y la parte posterior al separador. Si no se encuentra el separador, devuelva una tupla que contenga la cadena, seguida de dos cadenas vacías.

Nuevo en la versión 2.5.

>>> inputstr = "length=25" >>> inputstr.partition("=") (''length'', ''='', ''25'') >>> name, _, value = inputstr.partition("=") >>> print name, value length 25

También funciona para cadenas que no contienen el = :

>>> inputstr = "DEFAULT_VALUE" >>> inputstr.partition("=") (''DEFAULT_VALUE'', '''', '''')

Si, por algún motivo, está utilizando una versión de Python antes de la versión 2.5, puede usar la división de listas para hacer lo mismo, aunque sea un poco menos ordenado:

>>> x = "DEFAULT_LENGTH" >>> a = x.split("=")[0] >>> b = "=".join(x.split("=")[1:]) >>> print (a, b) (''DEFAULT_LENGTH'', '''')

.. y cuando x = "length=25" :

(''length'', ''25'')

Se convierte fácilmente en una función o lambda:

>>> part = lambda x: (x.split("=")[0], "=".join(x.split("=")[1:])) >>> part("length=25") (''length'', ''25'') >>> part(''DEFAULT_LENGTH'') (''DEFAULT_LENGTH'', '''')


No recomiendo usar esto, pero solo por diversión, aquí hay un código que realmente hace lo que quieres. Cuando llama a unpack(<sequence>) , la función de unpack usa el módulo de inspect para encontrar la línea real de la fuente donde se llamó a la función, luego usa el módulo ast para analizar esa línea y contar el número de variables desempaquetadas.

Advertencias:

  • Para la asignación múltiple (por ejemplo, (a,b) = c = unpack([1,2,3]) ), solo usa el primer término en la asignación
  • No funcionará si no puede encontrar el código fuente (por ejemplo, porque lo está llamando desde la respuesta)
  • No funcionará si la instrucción de asignación abarca varias líneas

Código:

import inspect, ast from itertools import islice, chain, cycle def iter_n(iterator, n, default=None): return islice(chain(iterator, cycle([default])), n) def unpack(sequence, default=None): stack = inspect.stack() try: frame = stack[1][0] source = inspect.getsource(inspect.getmodule(frame)).splitlines() line = source[frame.f_lineno-1].strip() try: tree = ast.parse(line, ''whatever'', ''exec'') except SyntaxError: return tuple(sequence) exp = tree.body[0] if not isinstance(exp, ast.Assign): return tuple(sequence) exp = exp.targets[0] if not isinstance(exp, ast.Tuple): return tuple(sequence) n_items = len(exp.elts) return tuple(iter_n(sequence, n_items, default)) finally: del stack # Examples if __name__ == ''__main__'': # Extra items are discarded x, y = unpack([1,2,3,4,5]) assert (x,y) == (1,2) # Missing items become None x, y, z = unpack([9]) assert (x, y, z) == (9, None, None) # Or the default you provide x, y, z = unpack([1], ''foo'') assert (x, y, z) == (1, ''foo'', ''foo'') # unpack() is equivalent to tuple() if it''s not part of an assignment assert unpack(''abc'') == (''a'', ''b'', ''c'') # Or if it''s part of an assignment that isn''t sequence-unpacking x = unpack([1,2,3]) assert x == (1,2,3) # Add a comma to force tuple assignment: x, = unpack([1,2,3]) assert x == 1 # unpack only uses the first assignment target # So in this case, unpack(''foobar'') returns tuple(''foo'') (x, y, z) = t = unpack(''foobar'') assert (x, y, z) == t == (''f'', ''o'', ''o'') # But in this case, it returns tuple(''foobar'') try: t = (x, y, z) = unpack(''foobar'') except ValueError as e: assert str(e) == ''too many values to unpack'' else: raise Exception("That should have failed.") # Also, it won''t work if the call spans multiple lines, because it only # inspects the actual line where the call happens: try: (x, y, z) = unpack([ 1, 2, 3, 4]) except ValueError as e: assert str(e) == ''too many values to unpack'' else: raise Exception("That should have failed.")


No uses este código, está pensado como una broma, pero hace lo que quieres:

a = b = None try: a, b = [a for a in ''DEFAULT_LENGTH''.split(''='')] except: pass


Podrías escribir una función de ayuda para hacerlo.

>>> def pack(values, size): ... if len(values) >= size: ... return values[:size] ... return values + [None] * (size - len(values)) ... >>> a, b = pack(''a:b:c''.split('':''), 2) >>> a, b (''a'', ''b'') >>> a, b = pack(''a''.split('':''), 2) >>> a, b (''a'', None)


Se han propuesto muchas otras soluciones, pero tengo que decir que la más directa para mí todavía es

a, b = string.split("=") if "=" in string else (string, None)


# this will result in a="length" and b="25" a, b = "length=25".partition("=")[::2] # this will result in a="DEFAULT_LENGTH" and b="" a, b = "DEFAULT_LENGTH".partition("=")[::2]