2009-06-15 9 views
26

Una funzione dovrebbe selezionare le righe in una tabella in base al nome della riga (colonna 2 in questo caso). Dovrebbe essere in grado di prendere un solo nome o un elenco di nomi come argomenti e gestirli correttamente.Gestire una lista o un singolo numero come argomento

Questo è quello che ho adesso, ma idealmente non ci sarebbe questo codice duplicato e qualcosa come eccezioni sarebbero stati utilizzati in modo intelligente per scegliere il modo giusto per gestire l'argomento di input:

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) 

risposta

18

In realtà sono d'accordo con Andrew Hare sopra, basta passare una lista con un singolo elemento.

Ma se davvero devi accettare un non-elenco, che ne dici di trasformarlo in un elenco in quel 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 penalizzazione delle prestazioni per fare 'in' in un elenco singolo elemento non è probabile che sia di alta :-) Ma ciò fanno notare un'altra cosa che si potrebbe prendere in considerazione di fare se il vostro 'to_select 'la lista potrebbe essere lunga: considera di lanciarla su un set in modo che le ricerche siano più efficienti.

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

lo farei proprio questo:

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) 

e si aspetta che l'argomento sia sempre un elenco - anche se è solo un elenco di un elemento.

Ricorda:

E 'più facile chiedere perdono che il permesso.

+1

+1 ... molto più facile mantenere solo un set di codice per eseguire un compito e più pythonic; lascia che esploda se qualcuno lo chiama in barba ai documenti. Se è veramente necessaria una funzione che accetta un singolo intero come argomento, creane una seconda chiamata "def select_row (to_select)" e assegnagli il pacchetto "to_select" come elenco, quindi chiama select_rows. –

14

Si potrebbe ridefinire la funzione di prendere qualsiasi numero di argomenti, in questo modo:

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

Poi si può passare un solo argomento come questo:

select_rows('abc') 

più argomenti come questo:

select_rows('abc', 'def') 

E se si dispone già di un t:

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

+1 Come questo approccio migliore di quello di Andrew Hare ...Il problema potrebbe essere se fosse necessario passare più argomenti alla stessa funzione, non solo la lista/singolo argomento. Ma potresti averli prima o usare gli argomenti delle parole chiave, ad esempio ** kwargs. – Jaime

+0

Questa risposta è chiaramente migliore. +1 Codice auto-documentante. * args implora per un iterable. – tortal

3

mi piacerebbe andare con la versione di Sharkey, ma uso un po 'più duck typing:

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) 

Questo ha il vantaggio di lavorare con qualsiasi oggetto che supporta l'operatore in. Inoltre, la versione precedente, se fornita una tupla o qualche altra sequenza, la racchiudeva in una lista. Il rovescio della medaglia è che c'è qualche penalità di prestazioni per l'utilizzo della gestione delle eccezioni.

+0

Questo è problematico per unicode e stringhe. cf: http://stackoverflow.com/questions/305359/correct-way-to-detect-sequence-parameter/425567#425567 –

+0

Punto valido, dovrebbe essere stato almeno "in (elenco, tupla)" ... o forse "not in (string, unicode)". Preferibilmente, dovresti cercare direttamente "questo supporter 'in'", suppongo. – NickZoic

Problemi correlati