首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据值的上限/下限过滤字典列表

根据值的上限/下限过滤字典列表
EN

Stack Overflow用户
提问于 2020-11-17 17:25:19
回答 3查看 179关注 0票数 0

我有一个字典列表,我正在尝试为其编写一个过滤函数。过滤依据的参数将以字典的形式给出,其中关键字将是字符串(与要筛选的字典列表中的关键字匹配),值将是具有上限和下限的列表。

要过滤的字典示例列表:

代码语言:javascript
运行
复制
test_list = [{'hello':1, 'goodbye':4}, {'hello':7, 'goodbye':6}, {'hello': 4, 'goodbye': 2}]

过滤参数示例:

代码语言:javascript
运行
复制
params = {'hello':[1, 6], 'goodbye':[5, 8]}

我写的函数如下:

代码语言:javascript
运行
复制
def filter_list(target_list, **kwargs):
    filtered_list = target_list
    for k,v in kwargs.items():
        for target in filtered_list:
            if target[k]<v[0] or target[k]>v[1]:
                filtered_list.remove(target)
    return filtered_list

由于某些原因,第二个参数没有被检查,我得到的输出是:

代码语言:javascript
运行
复制
filter_it = filter_list(test_list, **params)
print(filter_it)

>>[{'hello': 4, 'goodbye': 2}]

为什么会这样呢?根据我的估计,字典列表中的条目都不应该通过标准。但如果我将参数更改为:

代码语言:javascript
运行
复制
params = {'hello':[1, 8], 'goodbye':[5, 8]}

输出现在是:

代码语言:javascript
运行
复制
>>[{'hello': 7, 'goodbye': 6}]

要使用它的实际数据是大约2500个字典的列表,每个字典大约有45-50个键:值对。我需要能够根据任意数量的参数进行过滤,因为我并不总是希望指定每个参数的上限和下限,因此我没有对每个参数进行硬编码比较。

提前感谢所有人/任何帮助!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-11-17 17:35:17

这就是你要找的东西吗?

代码语言:javascript
运行
复制
result = list(filter(lambda x: all(lower < x[key] < upper 
                                   for key, (lower, upper) in params.items()),
                     test_list))
票数 1
EN

Stack Overflow用户

发布于 2020-11-17 17:42:25

你在这段代码中有一个问题:

代码语言:javascript
运行
复制
for target in filtered_list:
      if target[k]>=v[0] and  target[k]<=v[1]:
            filtered_list.remove(target)

您正在从iterable Type中删除阻止您进行某些循环的项...这是一种过滤列表的方法,你最好这样做:

代码语言:javascript
运行
复制
filtered_list = [target for target in filtered_list if target[k]<v[0] or target[k]>v[1]]
票数 0
EN

Stack Overflow用户

发布于 2020-11-17 17:57:51

你已经得到了答案,所以我只给你一些额外的解释。

首先,您的代码在迭代列表时从列表中删除了一项。所以它会忽略一些项目。例如,当您删除列表的第二项时。然后,它将在下一次循环中获得第四项。

我已经修改了你的原始代码,所以你可以理解它应该是什么。

首先,您可以使用复制而不是移动。

代码语言:javascript
运行
复制
def filter_list_with_copy(target_list, **kwargs):
    filtered_list = []
    for target in target_list:
        all_satisfied = True
        for k, v in kwargs.items():
            if target[k] < v[0] or target[k] > v[1]:
                all_satisfied = False
                break
        if all_satisfied:
            filtered_list.append(target)
    return filtered_list

其次,您可以使用while代替for。然后你可以控制你的循环索引。

代码语言:javascript
运行
复制
def filter_list_with_while(target_list, **kwargs):
    filtered_list = target_list
    for k, v in kwargs.items():
        filtered_index = 0
        filtered_list_length = len(filtered_list)
        while filtered_index < filtered_list_length:
            target = filtered_list[filtered_index]
            if target[k] < v[0] or target[k] > v[1]:
                filtered_list.remove(target)
                filtered_list_length = len(filtered_list)
            else:
                filtered_index += 1
    return filtered_list
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64872496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档