Manejar una lista o un entero entero como un argumento

Una función debe seleccionar filas en una tabla según el nombre de la fila (columna 2 en este caso). Debería poder tomar un solo nombre o una lista de nombres como argumentos y manejarlos correctamente.

Esto es lo que tengo ahora, pero idealmente no habría este código duplicado y se usarían de manera inteligente algunas excepciones para elegir la forma correcta de manejar el argumento de entrada:

def select_rows(to_select): # For a list for row in range(0, table.numRows()): if _table.item(row, 1).text() in to_select: table.selectRow(row) # For a single integer for row in range(0, table.numRows()): if _table.item(row, 1).text() == to_select: table.selectRow(row) 

En realidad estoy de acuerdo con la respuesta de Andrew Hare , simplemente pase una lista con un solo elemento.

Pero si realmente debe aceptar una no-lista, ¿qué tal si simplemente la convierte en una lista en ese caso?

 def select_rows(to_select): if type(to_select) is not list: to_select = [ to_select ] for row in range(0, table.numRows()): if _table.item(row, 1).text() in to_select: table.selectRow(row) 

La penalización de rendimiento por hacer “in” en una lista de un solo elemento probablemente no sea alta 🙂 Pero eso indica otra cosa que debería considerar si su lista ‘to_select’ puede ser larga: considere la posibilidad de elegir a un conjunto para que las búsquedas sean más eficientes.

 def select_rows(to_select): if type(to_select) is list: to_select = set( to_select ) elif type(to_select) is not set: to_select = set( [to_select] ) for row in range(0, table.numRows()): if _table.item(row, 1).text() in to_select: table.selectRow(row) 

Podría redefinir su función para tomar cualquier número de argumentos, como este:

 def select_rows(*arguments): for row in range(0, table.numRows()): if _table.item(row, 1).text() in arguments: table.selectRow(row) 

Entonces puedes pasar un solo argumento como este:

 select_rows('abc') 

múltiples argumentos como este:

 select_rows('abc', 'def') 

Y si ya tienes una lista:

 items = ['abc', 'def'] select_rows(*items) 

Yo haría esto:

 def select_rows(to_select): # For a list for row in range(0, table.numRows()): if _table.item(row, 1).text() in to_select: table.selectRow(row) 

y espere que el argumento siempre sea una lista, incluso si solo es una lista de un elemento.

Recuerda:

Es más fácil pedir perdón que permiso.

Estaría de acuerdo con la versión de Sharkey, pero uso un poco más de escritura de pato:

 def select_rows(to_select): try: len(to_select) except TypeError: to_select = [to_select] for row in range(0, table.numRows()): if _table.item(row, 1).text() in to_select: table.selectRow(row) 

Esto tiene la ventaja de trabajar con cualquier objeto que sea compatible con el operador in. Además, la versión anterior, si se le da una tupla o alguna otra secuencia, simplemente la incluiría en una lista. El inconveniente es que hay alguna penalización de rendimiento por el uso del manejo de excepciones.