Pregunta

Poder validar los elementos de la lista usando choices=servers Abajo está bien.

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')

¿Es posible forzar que un elemento en la lista sea único, para que no se permitan duplicados?

¿Fue útil?

Solución

La forma de descartar correctamente los duplicados usando argparse sería crear el tuyo argparse.Action clase que se encarga de usar set Según lo sugerido por otras respuestas:

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()

Salida de ejemplo:

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

Otros consejos

No creo que puedas hacer cumplir esto con argparse, pero tampoco veo ninguna razón para hacerlo. Solo documente en help que se ignoran los duplicados. Si el usuario pasa argumentos duplicados a --only, solo déjala hacerlo e ignora el argumento duplicado al procesar los argumentos de opción (por ejemplo, al tirar la lista en un set() antes del procesamiento).

Modificación de la respuesta de 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]

Mucho más corto.

Aquí hay un extracto de algún código que uso para un propósito similar:

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')

Esto es similar en espíritu a la respuesta de JCollado, con una mejora modesta: se pueden especificar múltiples opciones, con valores separados por comas, y se dedican (a través de SET) en todas las opciones.

Por ejemplo:

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

Tenga en cuenta que hay dos args de -g. BRCA2 se especifica dos veces en el primero, pero aparece solo una vez. BRCA1 se especifica en la primera y segunda opción, pero también aparece solo una vez.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top