Digamos que tengo un typing.List[str] que contiene marcas de tiempo en formato "HH:mm" , por ejemplo
timestamps = ["22:58", "03:11", "12:21"] Quiero convertirlo en un typing.List[int] con los valores de "número de minutos desde la medianoche" para cada marca de tiempo:
converted = [22*60+58, 3*60+11, 12*60+21]... pero quiero hacerlo con estilo y usar una sola lista de comprensión para hacerlo. Una implementación (sintácticamente incorrecta) que construí ingenuamente fue algo así como:
def timestamps_to_minutes(timestamps: typing.List[str]) -> typing.List[int]: return [int(hh) * 60 + int(mm) for ts in timestamps for hh, mm = ts.split(":")] ... pero esto no funciona porque for hh, mm = ts.split(":") no es una sintaxis válida.
¿Cuál sería la forma válida de escribir lo mismo?
Para aclarar: puedo ver una solución formalmente satisfactoria en la forma de:
def timestamps_to_minutes(timestamps: typing.List[str]) -> typing.List[int]: return [int(ts.split(":")[0]) * 60 + int(ts.split(":")[1]) for ts in timestamps]... pero esto es muy ineficiente y no quiero dividir la cadena dos veces.
Podría usar una expresión generadora interna para hacer la división:
[int(hh)*60 + int(mm) for hh, mm in (ts.split(':') for ts in timestamps)]Aunque personalmente, prefiero usar una función de ayuda en su lugar:
def timestamp_to_minutes(timestamp: str) -> int: hh, mm = timestamp.split(":") return int(hh)*60 + int(mm) [timestamp_to_minutes(ts) for ts in timestamps] # Alternative list(map(timestamp_to_minutes, timestamps))Si no desea dividir la cadena dos veces, puede usar := operador de asignación:
timestamps = [int((s := t.split(":"))[0]) * 60 + int(s[1]) for t in timestamps] print(timestamps)Huellas dactilares:
[1378, 191, 741]Alternativa:
print([int(h) * 60 + int(m) for h, m in (t.split(":") for t in timestamps)])Huellas dactilares:
[1378, 191, 741]Nota:
:=es una característica de Python 3.8+ comúnmente conocida como el " operador morsa ". Aquí el PEP con la propuesta.
Tu pseudocódigo inicial
[int(hh) * 60 + int(mm) for ts in timestamps for hh, mm = ts.split(":")]está bastante cerca de lo que puedes hacer:
[int(hh) * 60 + int(mm) for ts in timestamps for hh, mm in [ts.split(':')]]En Python 3.9, expresiones como esta se optimizaron para que crear una matriz de un solo elemento dentro de una comprensión solo para acceder a su único elemento de inmediato sea tan rápido como una simple asignación.