3

我有一个对象列表。每个对象都是一个唯一的实例,由名称和值的任意组合组成。我想将具有重复名称的对象组合到同一类的新实例中,其值是所有重复项的值的列表。这是我非常非pythonic的方法:

def normalise_repeatable_options(options):
    flat = {}
    for o in options:
        if isinstance(o, Option):
            flat.setdefault(o.long, []).append(o)

    # Ensure options stay in the order they were prescribed.
    parsed = []
    for o in options:
        if isinstance(o, Option):
            dups = flat.get(o.long)
            if dups:
                parsed.append(Option.combine(*tuple(dups)))
                del flat[o.long]
        else:
            parsed.append(o)

    return parsed

更新:函数的输入和预期输出

input = [
    Option('-f', '--filter', 1, 'merge file'),
    Option('-f', '--filter', 1, 'merge anotherfile'),
    Argument(None, 'a'),
    Argument(None, 'b'),
    Argument(None, 'c')
]

output = [
    Option('-f', '--filter', 1, ['merge file', 'merge anotherfile']),
    Argument(None, 'a'),
    Argument(None, 'b'),
    Argument(None, 'c')
]

我还包括了Object.combine类方法,以防你想知道它的作用:

@classmethod
def combine(class_, *opts):
    t = opts[0]
    if len(opts) == 1: return t
    return class_(t.short, t.long, t.argcount, [o.value for o in opts])
4

3 回答 3

1

在无法测试的情况下,关于这样的事情?

def normalise_repeatable_options(options):
    parsed = []
    flat = defaultdict(list)

    for o in options:
        if isinstance(o, Option):
            # For the first instance of this object, add a placemarker
            if o.long not in flat:
                parsed.append(o.long)

            flat[o.long].append(o)
        else:
            parsed.append(o)

    return [Option.combine(*tuple(flat[o])) if isinstance(o, str) else o for o in parsed]

这样,您就可以构建列表,为要替换parsed的对象留下地标。Option我假设您输入列表中的所有对象都不是 type str

于 2013-10-12T02:15:35.997 回答
1

你可以从这里开始:

from collections import defaultdict

def normalise_repeatable_options(options):
    actual_options = [o for o in options if isinstance(o, Option)]
    non_options = [o for o in options if not isinstance(o, Option)]

    flat = defaultdict(list)
    for o in actual_options:
        flat[o.long].append(o)

    parsed = (
        # Make list of the non-options plus ...
        non_options +

        # a flattened lists of Options plus ...
        [Option.combine(*tuple(dups)) for dup in flat.values() if len(dup) > 1] +

        # a list of Options
        [value[0] for value in flat.values() if len(value) == 1]
    )
    return parsed
于 2013-10-12T02:16:51.060 回答
0

尝试列表理解:)

不确定这是否适用于您的情况,因为我根据一个代码到另一个代码的简单映射来修改您的代码。

您可以通过 check isinstance 获得公寓,因此您无需再次检查。

这段代码可能有小错误:

def normalise_repeatable_options(options):
    flat = {}
    parsed = []
    [flat.setdefault(o.long, []).append(o) if isinstance(o, Option)
     else parsed.append(o) for o in options]

    [parsed.append(Option.combine(*tuple(lst))) if len(lst) > 1 
     else parsed.append(lst) for lst in flat.values()]

    return parsed
于 2013-10-12T02:14:33.450 回答