字典推导式与条件调用嵌套列表推导式

4
我有一个键和列表的字典。我想遍历这个字典,获取每个列表,遍历每个列表并应用条件,然后将筛选后的列表追加到一个新的字典中。
该函数已经以命令式方式工作。我能否使用列表和字典推导式进行相同的功能呢?主要的障碍是包装字典推导式需要列表推导式的长度来进行条件判断。
这里是它以命令式方式工作的样子:
filtered_prediction_dict = {}
for prediction, confidence_intervals in prediction_dict.items():
    filtered_confidence_intervals = []
    for i in confidence_intervals:
        if i > threshold:
            filtered_confidence_intervals.append(i)
    if len(filtered_confidence_intervals) >= 1:
        filtered_prediction_dict[prediction] = filtered_confidence_intervals

我在想是否可以使用推导式以函数方式完成相同的操作,就像这样:

我在想是否可以使用推导式以函数方式完成相同的操作,就像这样:

filtered_prediction_dict = {prediction: [i for i in confidence_intervals if i > threshold] for prediction, confidence_intervals in prediction_dict.items() if len(filtered_confidence_intervals) >= 1}

当然,Python的linter指出,在条件语句中的len(filtered_confidence_intervals)未被定义。
有什么方法可以解决这个问题吗?

“我在想是否可以使用推导式在功能上做同样的事情”,但如果您希望从一周后开始理解您的代码,请不要这样做。 - DeepSpace
只需将 filtered_confidence_intervals 改为列表推导式即可,但其他部分保持不变。 - jonrsharpe
这些答案对你有帮助吗? - j-i-l
是的,我希望有一种元方法可以避免两次计算列表推导式,但似乎不可避免。any()函数非常有用。 - Hung-Ray Ho
2个回答

3

你可以在单个语句中放置你对每个置信区间应用的两个条件。此外,无论如何我建议将置信区间的过滤器放在列表理解语句中。

这两个条件:

  1. 置信区间 > 阈值(if i > threshold
  2. 一个或多个置信区间大于阈值(len(filtered_confidence_intervals) >= 1

用单个语句表达:

  • any(ci > threshold for ci in confidence_intervals)

结果列表推导版本(为了可读性而分开):

{
    p: [ci for ci in cis if ci > threshold]  # only keep ci > threshold
    for p, cis in prediction_dict.items()  # iterate through the items
    if any(ci > threshold for ci in cis)  # only consider items with at least one ci > threshold
}

我认为这种写法不比使用for循环差,但我想这是个人口味和用途的问题。


如果你想继续使用for循环:

filtered_prediction_dict = {}
for prediction, confidence_intervals in prediction_dict.items():
    if any(ci > threshold for ci in confidence_intervals):
        filtered_prediction_dict[prediction] = [ci for ci in confidence_intervals if ci > threshold]

针对你关于Python的linter指出 filtered_confidence_intervals 还未定义的评论:

通常情况下,linters是非常准确的,这种情况也不例外。因为filtered_confidence_intervals 在每个 prediction_dict 的项中都有定义,所以您无法遍历整个 prediction_dict 并测试 filtered_confidence_intervals 的长度。

您需要替换此语句:

len(filtered_confidence_intervals) >= 1

在列表推导式中
len([ci for ci in confidence_intervals if ci > threshold]) >= 1

2

您可以使用:

filtered_prediction_dict = {prediction: [i for i in confidence_intervals if i > threshold] for prediction, confidence_intervals in prediction_dict.items() if any(e >= threshold for e in  confidence_intervals)}

以这种方式,您可以检查您的filtered_prediction_dict是否具有任何空列表。
或者您可以使用:
filtered_prediction_dict = {prediction: [i for i in confidence_intervals if i > threshold] for prediction, confidence_intervals in prediction_dict.items() if max(confidence_intervals) >= threshold}

第二个版本对列表中的每个元素进行了两次迭代,第一个版本有一些冗余的迭代,但即便如此,这两个解决方案都可能比使用for语句更快。

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