根据共同项在Python中缩小列表

3

我希望进行如下转换:

['test.smth.test', 'test.smth'] -> ['test.smth']
['test.smth.test', 'test.smth.another'] -> ['test.smth.test', 'test.smth.another']
['test.one', 'test.smth'] -> ['test.one', 'test.smth']
['test.one', 'test', 'test.smth.name'] -> ['test']
['test_another.one.name', 'test', 'test.smth.name'] -> ['test', 'test_another.one.name']

我最终得到的代码是:

def format_fields(fields):
    fields_data = defaultdict(list)
    for field in fields:
        split = field.split('.')
        base = split[0]
        already = False
        for i in reversed(range(len(split))):
            if split[:i] in fields_data[base]:
                already = True
                break
        if already:
            continue
        current = [i for i in fields_data[base] if len(i) < len(split)
                   or i[len(split) - 1] != split[-1]]
        fields_data[base] = current + [split]
    return ['.'.join(value) for group in fields_data.values() for value in group]

这个方法似乎可行,但是是否有更易读/更聪明的解决方案,或者有第三方库可以实现这个功能?


看起来你有一个图,想要获取没有子节点的节点... - Jon Clements
1个回答

1
这应该有效,基本上你需要找到每个不包含在任何其他字段中的字段,在每个字段末尾添加一个点可以避免子字符串错误,例如'test_another'和'test':
cases = [
  ['test.smth.test', 'test.smth'],
  ['test.smth.test', 'test.smth.another'],
  ['test.one', 'test.smth'],
  ['test.one', 'test', 'test.smth.name'],
  ['test_another.one.name', 'test', 'test.smth.name']
]

def filterFields(fields):
  cFields = [field + '.' for field in fields]
  return [field[:-1] for index, field in enumerate(cFields) if all(field.find(f) != 0 for f in cFields[:index] + cFields[index+1:])]

for case in cases:
  print(case, '->', filterFields(case))

工作代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接