过滤嵌套列表

8

我想通过另一个长度可变的列表过滤嵌套列表。如果子列表中的任何项与过滤列表中的任何元素匹配,则应排除该子列表。以下代码适用于我,但是否有更“简洁”的解决方案?

the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'], ['yellow', 'green'], ['orange'], ['white', 'gray']]
filters = ['blue', 'white']

filtered_list = []
for sublist in the_list:
    for item in sublist:
        if item in filters:
            break
        filtered_list.append(sublist)
        break

期望输出:

filtered_list = [['green', 'yellow'], ['yellow', 'green'], ['orange']]

2
如果您提供一个样本输入输出对,可能会有所帮助。 - John Coleman
1
你可以使用 continue 来代替第一个 break。我认为第一个 break 会导致 sublist in item 循环停止。 - AetherUnbound
@JohnColeman 添加了样例输入输出。 - tenac
8个回答

5
也许更语义化的做法是使用any
for sublist in the_list:
    if any(item in filters_exclude for item in sublist):
        continue
    filtered_list.append(sublist)

也许有些冗余,但你甚至可以将它因素化为自己的函数,然后使用内置的filter函数。
def good_list(some_list):
    return not any(item in filters_exclude for item in some_list)

filtered_list = filter(good_list, the_list)

这应该可以实现您所描述的目标。然而,正如评论中提到的那样,您编写的代码存在潜在问题。

4
你可以使用列表推导式:
```python ```
the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'],['orange'], ['white', 'gray']]
filters = ['blue', 'white']
final_l = [i for i in the_list if not any(b in filters for b in i)]

输出:

[['green', 'yellow'], ['orange']]

或者,使用过滤器:

final_l = filter(lambda x:not any(b in filters for b in x), the_list)

3
你可以使用filtermap让这个代码成为“一行代码”。虽然不会提高可读性,但它是有效的:
filters_exclude = [2, 4]
initial_list = [[1, 2, 3, 4], [1, 2, 3], [2, 3, 4, 5]]

final = list(map(lambda x: filter(lambda y: y not in filters_exclude, x), initial_list)

例子:

>>> filters_exclude = [2, 4]
>>> map(lambda x: filter(lambda y: y not in filters_exclude, x), [[1, 2, 3, 4], [1, 2, 3]])
[[1, 3], [1, 3]]

3
你可以使用条件列表推导式。
>>> [sublist for sublist in the_list 
     if all(filter not in set(sublist) for filter in filters)]
[['green', 'yellow'], ['orange']]

3

您还可以使用Set intersection过滤掉与列表filters没有交集的列表,使用filter()方法:

>>> the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'], ['yellow', 'green'], ['orange'], ['white', 'gray']]
>>> filters = ['blue', 'white']
>>> list(filter(lambda x: not set(x).intersection(filters), the_list))
[['green', 'yellow'], ['yellow', 'green'], ['orange']]

或者使用理解:

>>> [x for x in the_list if not set(x).intersection(filters)]
[['green', 'yellow'], ['yellow', 'green'], ['orange']]

3

使用集合。

the_list = map(set, the_list)
filters = set(filters)

fl = []
for sub in the_list:
    sub = sub.difference(filters)
    if sub:
        fl.append(list(sub))

2
这与您所拥有的非常接近。
最初的回答:这几乎就是您拥有的内容。
    the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'], 
    ['yellow', 'green'], ['orange'], ['white', 'gray']]
    filters = ['blue', 'white']

    filtered_list = []

    for sublist in the_list:
        sub_filtered_list=[]
        for item in sublist:
           if item in filters:
                continue
            else:
                sub_filtered_list.extend([item])
        if sub_filtered_list==[]:
            continue
        else:
            filtered_list.append(sub_filtered_list)

    print(filtered_list)

1
filtered_list=[];
for sublist in the_list:
    if len(list(set(sublist).intersection(filters_exclude)))>0:
        break;
    filtered_list.append(sublist);

set(sublist).intersection(filters_exclude) 返回两个列表的交集。List() 将 set 转换为 List。Len() 返回 List 的长度。


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