2009-06-15 5 views
26

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.Maneja una lista o entero simple como argumento

Esto es lo que tengo ahora, pero lo ideal sería que no habría este código duplicado y algo así como las excepciones son utilizados de forma inteligente para elegir el camino correcto para 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) 

Respuesta

18

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

Pero si realmente debe aceptar una lista no, ¿qué tal si 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 para hacer 'en' en una lista de un solo artículo no es probable que sea alta :-) Pero eso sí señala otra cosa es posible que desee considerar hacer si su 'to_select La lista puede ser larga: considere enviarla 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) 

----- N

11

Haría sólo 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 esperamos que el argumento siempre sea una lista, incluso si es solo una lista de un elemento.

Recuerde:

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

+1

+1 ... mucho más fácil mantener solo un conjunto de código para realizar una tarea, y más pitónico; déjalo explotar si alguien lo llama desafiando a los documentos. Si se necesita realmente una función que acepte un solo entero como argumento, haga una segunda llamada 'def select_row (to_select)' y pídala 'como_selección' como una lista, luego llame a select_rows. –

14

Se podría volver a definir su función para tomar cualquier número de argumentos, así:

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

entonces puede pasar un solo argumento así:

select_rows('abc') 

múltiples argumentos como este:

select_rows('abc', 'def') 

Y si ya tiene una lis t:

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

+1 Me gusta este enfoque mejor que el de Andrew Hare ...El problema podría ser si necesita pasar más argumentos a la misma función, no solo la lista/un solo argumento. Pero podría tenerlos antes o usar argumentos de palabra clave, es decir, ** kwargs. – Jaime

+0

Esta respuesta es claramente mejor. +1 Código de auto-documentación. * args pide un iterable. – tortal

3

me gustaría ir junto con la versión de Sharkey, pero el uso de un poco más de pato escribiendo:

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 admite el operador in. Además, la versión anterior, si se le da una tupla u otra secuencia, simplemente la incluiría en una lista. La desventaja es que hay una cierta penalización de rendimiento por usar el manejo de excepciones.

+0

Este es problemático para unicodes y cadenas. cf: http://stackoverflow.com/questions/305359/correct-way-to-detect-sequence-parameter/425567#425567 –

+0

Punto válido, al menos debería haber sido "in (list, tuple)" ... o tal vez "no en (cadena, unicode)". Preferentemente, querría buscar directamente "¿este soporte de cosas en '?", Supongo. – NickZoic

Cuestiones relacionadas