Tengo una función que toma como argumento una lista de objetos o un solo objeto. Luego quiero recorrer los elementos de la lista u operar en el único objeto si no es una lista.

A continuación, uso numpy.atleast_1d().tolist() para asegurarme de que un bucle funcione independientemente de si el argumento es una lista o un solo objeto. Sin embargo, no estoy seguro de si convertir el objeto a una matriz numpy y luego a una lista puede causar cambios no deseados en el objeto.

¿Hay alguna manera de garantizar que el argumento se transforme en una lista si no es una lista? Tengo dos posibles soluciones en un ejemplo simple a continuación, pero quería saber si hay otras mejores.

import numpy as np

def printer1(x):
    for xi in np.atleast_1d(x).tolist():
        print(xi)

def printer2(x):
    if type(x) != list:
        x = [x]

    for xi in x:
        print(xi)

x1 = 'a'
x2 = ['a','b','c']

printer1(x1)
printer1(x2)

printer2(x1)
printer2(x2)

Estoy usando Python 2.7

0
profj 2 oct. 2019 a las 22:10

4 respuestas

La mejor respuesta
  • En su función puede agregar check para array. Creo que esta es una forma de hacerlo. Ni siquiera necesita usar numpy para esto.
def foo(x):
  x = [x] if not isinstance(x, list) else x
  printx # or do whatever you want to do
  # or
  for value in x:
    print value


foo('a')
foo(['a','b'])

salida:

['a']
a
['a', 'b']
a
b
1
Poojan 2 oct. 2019 a las 19:23

Si desea que las cosas en bucle, en su mayoría intactas y no en bucle, se comporten como una lista de 1 elemento, puede hacer algo como:

def forceiter(x):
    return getattr(x,"__iter__",lambda:(x,))()

Demo:

for x in [1,[2],range(3),"abc",(),{3:3,4:"x"}, np.logspace(0,3,4)]:
    print(x,end="  -->  ")
    for i in forceiter(x):
        print(i,end=" ")
    print()

# 1  -->  1 
# [2]  -->  2 
# range(0, 3)  -->  0 1 2 
# abc  -->  a b c 
# ()  -->  
# {3: 3, 4: 'x'}  -->  3 4 
# [   1.   10.  100. 1000.]  -->  1.0 10.0 100.0 1000.0 
1
Paul Panzer 3 oct. 2019 a las 04:40

Como dice Roni, puedes usar esto:

def printer(x):
  finalList = []
  finalList.extend(x)

  print finalList

Si x es un valor único, se agregará a finalList, si x es una lista, se unirá a finalList y podrá iterar a través de él.

1
Arthur Lyrio de Oliveira 2 oct. 2019 a las 19:48

Para asegurarse de que el elemento será una lista incluso si tiene un solo elemento, declare su valor entre corchetes:

foo = ['stringexample']
foo2 = ['a','b']

for foos in foo:
    print (foos)

for foos2 in foo2:
    print (foos2)

De esta manera, incluso ese 'foo' tiene una sola cadena, seguirá funcionando como una lista con un solo elemento.

Además, puedes probar esto:

declare a empty list 
use youremptylist.extend(incoming value)

Iterará una nueva lista para cada valor entrante, incluso si es uno solo

1
Roni Antonio 2 oct. 2019 a las 19:46
58207931