我有一个对象列表。每个对象都是一个唯一的实例,由名称和值的任意组合组成。我想将具有重复名称的对象组合到同一个类的新实例中,其值是所有重复项的值的列表。这是我的非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])
答案 0 :(得分: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
对象留下placemarkers。我假设输入列表中没有任何对象属于str
类型。
答案 1 :(得分: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
答案 2 :(得分: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