Por lo general, las cadenas (plano y Unicode) son los únicos iterables que desee tener en cuenta, sin embargo, como "elementos individuales" - existe la basestring
incorporado específicamente para permitir que se prueba para uno u otro tipo de cuerdas con isinstance
, así que es muy ONU -grotty para ese caso especial ;-).
Así que mi enfoque sugerido para el caso más general es:
if isinstance(input, basestring): input = [input]
else:
try: iter(input)
except TypeError: input = [input]
else: input = list(input)
Ésta es la manera de tratar a cada iterables excepto las series como una lista directamente, cadenas y números y otros no iterables como escalares (siendo normalizado en listas de elementos individuales).
Estoy haciendo explícitamente una lista de cada tipo de iterable para que sepa que puede realizar CUALQUIER tipo de truco de lista: ordenar, iterar más de una vez, agregar o eliminar elementos para facilitar la iteración, etc., todo sin alterando la lista de entrada REAL (si la lista era ;-). Si todo lo que necesita es un solo bucle sencillo for
entonces ese último paso no es necesario (y de hecho poco útil si, por ejemplo entrada es un archivo abierto enormes) y me gustaría sugerir un generador auxiliar en su lugar:
def justLoopOn(input):
if isinstance(input, basestring):
yield input
else:
try:
for item in input:
yield item
except TypeError:
yield input
ahora en todos y cada uno una de sus funciones que necesitan dicha normalización argumento, sólo tiene que utilizar:
for item in justLoopOn(input):
puede utilizar un normalizador-función auxiliar incluso en el otro caso (donde se necesita una lista de bienes a efectos más nefastos); En realidad, en tales casos (raros), sólo puede hacer:
thelistforme = list(justLoopOn(input))
por lo que la lógica de normalización (inevitablemente) un poco peludo es en un solo lugar, como debe ser -)
re: proper. En Python, el término usual es 'Pythonic'. Reconoce que hay muchas maneras de hacer algo, pero que algunas están más en el espíritu del lenguaje. –