0

我有一个路径列表,我想只保留不是任何其他项目前缀的项目。

例如,在以下列表中:

private
private/etc
private/etc/pam.d
usr
usr/local
usr/local/lib
usr/local/lib/security

我只想保留:

private/etc/pam.d
usr/local/lib/security

我不喜欢“发明轮子”并实现前缀树,而是使用已经这样做的 python 包。

谢谢!

4

3 回答 3

1

如果您的列表已排序,则每个项目都是以下任何一项的前缀或不是以下任何一项的前缀。

因此,您可以编写:

ls.sort()
[ls[i] for i in range(len(ls))[:-1] if ls[i] != ls[i+1][:len(ls[i])]] + [ls[-1]]

另一种实现,使用 zip:

[x for x, y in zip(ls[:-1], ls[1:]) if x != y[:len(x)]] + [ls[-1]]
于 2020-05-02T12:49:43.990 回答
1

我不知道任何包,但应该这样做:

#a is the list of items
for i in range(len(a)):
    for j in range(i, len(a)):
        if (a[i] in a[j]) and len(a[i]) < len(a[j]):
            a[i] = 'delete'

a = [i for i in a if i!= 'delete'] #new list without prefixed elements
于 2020-05-02T12:50:57.173 回答
-1

我觉得这可以通过使用子字符串来解决,即您正在寻找一个不是任何其他字符串的子字符串的字符串。

这是java中的一个解决方案,您可以在python中使用相同的逻辑。

public static void findFullyQualifiedPaths() {

    List<String> paths = new ArrayList<>();
    paths.add("private");
    paths.add("private/etc");
    paths.add("private/etc/pam.d");
    paths.add("usr");
    paths.add("usr/local");
    paths.add("usr/local/lib");
    paths.add("usr/local/lib/security");

    System.out.println("Input Paths");
    System.out.println(paths);

    List<String> filteredPaths = new ArrayList<String>(paths);

    filteredPaths.removeIf(currentPath -> {
        for (String path : paths) {
            if ((!path.equals(currentPath)) && path.contains(currentPath)) {
                return true;
            }
        }
        return false;
    });
    System.out.println("Paths after removing the substrings");
    System.out.println(filteredPaths);
}

输出:

Input Paths
[private, private/etc, private/etc/pam.d, usr, usr/local, usr/local/lib, usr/local/lib/security]
Paths after removing the substrings
[private/etc/pam.d, usr/local/lib/security]
于 2020-05-05T17:24:15.970 回答