0

I have the below dictionary:

{'Closed': {'High': 33, 'Medium': 474, 'Low': 47, 'Critical': 6}, 'Impact Statement Pending': {'Low': 3, 'Medium': 1, 'Critical': 0, 'High': 0}, 'New': {'Low': 1, 'High': 2, 'Critical': 2, 'Medium': 2}, 'Remediation Plan Pending': {'Medium': 10, 'Low': 1, 'Critical': 1, 'High': 0}, 'Remedy in Progress': {'Medium': 36, 'Low': 18, 'High': 4, 'Critical': 1}}

How might I accomplish creating a list comprised of all values for a specified key? A list for all high values, or another list for all medium values?

The way I am currently accomplishing this doesn't seem like the best way. I've got a list of all severity levels, which I iterate over and compare such as shown below:

trace_list = ['High', 'Medium', 'Critical', 'Low']

total_status_dict = {'Closed': {'High': 33, 'Medium': 474, 'Low': 47, 'Critical': 6}, 'Impact Statement Pending': {'Low': 3, 'Medium': 1, 'Critical': 0, 'High': 0}, 'New': {'Low': 1, 'High': 2, 'Critical': 2, 'Medium': 2}, 'Remediation Plan Pending': {'Medium': 10, 'Low': 1, 'Critical': 1, 'High': 0}, 'Remedy in Progress': {'Medium': 36, 'Low': 18, 'High': 4, 'Critical': 1}}

for item in trace_labels:

     y_values = []

     for key, val in total_status_dict.items():
          for ke in total_status_dict[key]:
               if item is ke:
                    y_values.append(total_status_dict[key][ke])

1 Answer 1

1

Note: you are iterating over total_status_dict keys and appending results to a list. Remember that even if dictionaries are officially ordered in Python since 3.7 (see https://docs.python.org/3/whatsnew/3.7.html) you do not always control the Python version of the user. I would rather build a dict key -> item -> value, where key is Closed, Impact Statement Pending, ... and  item is one of the trace_labels than a dict key -> [values] where values is supposed to be ordered as in trace_labels.

Your code is not efficient because you iterate over trace_labels twice:

  • for item in trace_labels:
  • for ke intotal_status_dict[key]: if item is ke:`

How to iterate only once? Instead of building y_values lists one by one (with a whole iteration over total_status_dict each time), you can build several lists at once:

>>> trace_labels = ['High', 'Medium', 'Critical', 'Low']
>>> total_status_dict = {'Closed': {'High': 33, 'Medium': 474, 'Low': 47, 'Critical': 6}, 'Impact Statement Pending': {'Low': 3, 'Medium': 1, 'Critical': 0, 'High': 0}, 'New': {'Low': 1, 'High': 2, 'Critical': 2, 'Medium': 2}, 'Remediation Plan Pending': {'Medium': 10, 'Low': 1, 'Critical': 1, 'High': 0}, 'Remedy in Progress': {'Medium': 36, 'Low': 18, 'High': 4, 'Critical': 1}}
>>> y_values_by_label = {}
>>> for key, value_by_label in total_status_dict.items():
...     for label, value in value_by_label.items(): # total_status_dict[key] is value_by_label
...         y_values_by_label.setdefault(label, {})[key] = value
...
>>> y_values_by_label
{'High': {'Closed': 33, 'Impact Statement Pending': 0, 'New': 2, 'Remediation Plan Pending': 0, 'Remedy in Progress': 4}, 'Medium': {'Closed': 474, 'Impact Statement Pending': 1, 'New': 2, 'Remediation Plan Pending': 10, 'Remedy in Progress': 36}, 'Low': {'Closed': 47, 'Impact Statement Pending': 3, 'New': 1, 'Remediation Plan Pending': 1, 'Remedy in Progress': 18}, 'Critical': {'Closed': 6, 'Impact Statement Pending': 0, 'New': 2, 'Remediation Plan Pending': 1, 'Remedy in Progress': 1}}

setdefault(label, {}) creates a empty dict y_values_by_label[label] = {} if y_values_by_label does not have the key label.

If you want to turn this in a dict comprehension, you have to use your inefficient method:

>>> {label:{k:v for k, value_by_label in total_status_dict.items() for l, v in value_by_label.items() if l==label} for label in trace_labels}
{'High': {'Closed': 33, 'Impact Statement Pending': 0, 'New': 2, 'Remediation Plan Pending': 0, 'Remedy in Progress': 4}, 'Medium': {'Closed': 474, 'Impact Statement Pending': 1, 'New': 2, 'Remediation Plan Pending': 10, 'Remedy in Progress': 36}, 'Critical': {'Closed': 6, 'Impact Statement Pending': 0, 'New': 2, 'Remediation Plan Pending': 1, 'Remedy in Progress': 1}, 'Low': {'Closed': 47, 'Impact Statement Pending': 3, 'New': 1, 'Remediation Plan Pending': 1, 'Remedy in Progress': 18}}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.