Domanda

Essere in grado di convalidare gli elementi dell'elenco utilizzando choices=servers Di seguito è bello.

servers = [ "ApaServer", "BananServer", "GulServer", "SolServer", "RymdServer", "SkeppServer", "HavsServer", "SovServer" ]
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--only', nargs='*', choices=servers, help='Space separated list of case sensitive server names to process')

È possibile forzare un elemento nell'elenco ad essere unico, in modo che non siano consentiti duplicati?

È stato utile?

Soluzione

Il modo per scartare correttamente i duplicati usando argparse Sarebbe creare il tuo argparse.Action classe che si occupa di usare set Come suggerito da altre risposte:

import argparse

class UniqueAppendAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        unique_values = set(values)
        setattr(namespace, self.dest, unique_values)

servers = ["ApaServer", "BananServer", "GulServer", "SolServer",
           "RymdServer", "SkeppServer", "HavsServer", "SovServer" ]
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--only', nargs='*', choices=servers, action=UniqueAppendAction,
                    help='Space separated list of case sensitive server names to process')
print parser.parse_args()

Esempio di output:

$ python test.py -o ApaServer ApaServer
Namespace(only=set(['ApaServer']))

Altri suggerimenti

Non credo, che puoi applicare questo con argparse, ma non vedo nemmeno alcun motivo per farlo. Basta documentare in help che i duplicati vengono ignorati. Se l'utente passa argomenti duplicati a --only, lascia che lo faccia e ignori l'argomento duplicato durante l'elaborazione degli argomenti dell'opzione (ad es. Turing dell'elenco in a set() prima di elaborazione).

Modifica della risposta di Michel:

In [1]: x = [5,6,5]

In [2]: x_nodups = list(set(x))

In [3]: x_nodups
Out[3]: [5, 6]

In [4]: x_nodups_michel = dict(map(lambda i: (i,1),x)).keys()

In [5]: x_nodups_michel
Out[5]: [5, 6]

Molto più breve.

Ecco un estratto di qualche codice che uso per uno scopo simile:

def parse_args(argv):
    class SetAction(argparse.Action):
        """argparse.Action subclass to store distinct values"""
        def __call__(self, parser, namespace, values, option_string=None):
            try:
                getattr(namespace,self.dest).update( values )
            except AttributeError:
                setattr(namespace,self.dest,set(values))
    ap = argparse.ArgumentParser(
        description = __doc__,
        formatter_class = argparse.ArgumentDefaultsHelpFormatter,
        )
    ap.add_argument('--genes', '-g',
                    type = lambda v: v.split(','),
                    action = SetAction,
                    help = 'select by specified gene')

Questo è simile nello spirito alla risposta di Jcollado, con un modesto miglioramento: è possibile specificare più opzioni, con valori separati da virgola e sono dedicate (tramite set) su tutte le opzioni.

Per esempio:

snafu$ ./bin/ucsc-bed -g BRCA1,BRCA2,DMD,TNFA,BRCA2 -g BRCA1
Namespace(genes=set([u'BRCA1', u'BRCA2', u'DMD', u'TNFA']))

Si noti che ci sono due args. BRCA2 è specificato due volte nel primo, ma appare solo una volta. BRCA1 è specificato nel primo e nel secondo Opts, ma appare anche solo una volta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top