简体   繁体   English

具有条件调用嵌套列表理解的字典理解

[英]dictionary-comprehension with conditional calling nested list-comprehension

I have a dictionary of keys and lists. 我有一个键和列表字典。 I'd like to iterate through the dictionary, get each list, iterate through each list and apply a condition, then append that filtered list to a new dictionary. 我想迭代字典,获取每个列表,遍历每个列表并应用条件,然后将过滤后的列表附加到新字典。

The function already works imperatively. 该功能已经势在必行。 Can I do the same functionally with list and dict comprehensions? 我可以使用list和dict理解在功能上做同样的事情吗? The main blocker is that the wrapping dict-comp has a conditional which needs length of the list-comp. 主要的阻塞是包装dict-comp有一个条件,需要list-comp的长度。

Here it is working imperatively: 这里的工作势在必行:

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

I was wondering if I could do the same thing functionally with comprehensions, something like this: 我想知道我是否可以在功能上用理解做同样的事情,像这样:

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}

Of course, python's linter points out that filtered_confidence_intervals hasn't yet been defined in len(filtered_confidence_intervals) in the conditional. 当然,python的linter指出尚未在条件中的len(filtered_confidence_intervals)中定义filtered_confidence_intervals。

Any way around this? 有什么方法吗?

You can put the two conditions you apply on each of the confidence intervals in a single statement. 您可以将您在每个置信区间上应用的两个条件放在一个语句中。 Also, I recommend putting the filtering for confidence intervals in a list comprehension statement in any case. 此外,我建议在任何情况下都将置信区间的过滤放在列表推导语句中。

The two conditions: 这两个条件:

  1. confidence interval > threshold (the if i > threshold ) 置信区间>阈值( if i > threshold
  2. one or more confidence intervals are are bigger than the threshold (the len(filtered_confidence_intervals) >= 1 ) 一个或多个置信区间大于阈值( len(filtered_confidence_intervals) >= 1

Expressed in a single statement: 用一个声明表达:

  • any(ci > threshold for ci in confidence_intervals)

The resulting list-comprehension version (split up for readability): 生成的列表理解版本 (为便于阅读而分开):

{
    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
}

IMHO this is not less readable than for -loops, but I guess this is a matter of taste and use. 恕我直言,这不小于可读for -loops,但我想这是品味和使用的问题。


If you want to keep for -looping: 如果你想保持for -looping:

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]

A note to your comment about the python's linter pointing out that filtered_confidence_intervals hasn't yet been defined: 关于python的linter的评论的注释,指出尚未定义filtered_confidence_intervals

Very often linters are quite accurate and this case is no exception. 很多时候,直径非常准确,这种情况也不例外。 filtered_confidence_intervals is defined per item in prediction_dict so there is no way you can iterate through prediction_dict and have a test about the length of filtered_confidence_intervals . filtered_confidence_intervals每项定义在prediction_dict所以没有办法,你可以通过迭代prediction_dict并有一个关于长度测试filtered_confidence_intervals

You would need to replace the statement: 你需要替换声明:

len(filtered_confidence_intervals) >= 1

in the list comprehension by 在列表中理解

len([ci for ci in confidence_intervals if ci > threshold]) >= 1

you can use: 您可以使用:

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)}

in this way you check that your filtered_prediction_dict doesn't have any empty list 通过这种方式,您可以检查您的filtered_prediction_dict没有任何空列表

or you can use: 或者您可以使用:

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}

the second version iterate twice over each element from your lists, the first has some redundant iterations, but even so both solutions may be faster than using for statements 第二个版本对列表中的每个元素进行两次迭代,第一个版本有一些冗余迭代,但即便如此,两个解决方案都可能比使用for语句更快

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM