繁体   English   中英

Python argparse:强制列表项是唯一的

[英]Python argparse: Force a list item to be unique

能够使用以下choices=servers来验证列表项是很好的。

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

是否可以强制列表中的项目是唯一的,以便不允许重复项?

使用argparse正确地丢弃重复项的方法是创建自己的argparse.Action类,该类负责使用其他答案建议的set

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

示例输出:

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

我不认为你可以用argparse强制执行此操作,但我也认为没有任何理由这样做。 只需在help中记录重复项被忽略。 如果用户将重复参数传递给--only ,则让她这样做,并在处理选项参数时忽略重复参数(例如,在处理之前将列表固定为set() )。

以下是我用于类似目的的一些代码的摘录:

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

这与jcollado的回复相似,只有适度的改进:可以指定多个选项,使用逗号分隔值,并在所有选项中重复(通过设置)。

例如:

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

请注意,有两个-g args。 BRCA2在第一个中指定了两次,但只出现一次。 BRCA1在第一个和第二个-g选项中指定,但也只出现一次。

修改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]

矮得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM