Jump to content

[Python] Looping through dicts and comparing

Shally

Hey guys,

So I have two dictionaries that look like this:
 

results = [
	{'id': '1', 'message': 'Queue does not have minimum required number of members. Required at least 5 but found 4.', 'decision': 'Failed'},
	{'id': '2', 'message': '', 'decision': ''}
]

metrics = {
	'results': [{
		'group': {
			'id': '1'
		},
		'data': [{
			'metrics': [{
				'result': {
					'count': 15
				}
			}]
		}]
	}, {
		'group': {
			'id': '2'
		},
		'data': [{
			'metrics': [{
				'results': {
					'count': 0
				}
			}]
		}]
	}]
}

I want to update the 'results' dictionary with where the 'decision' : 'Failed' if count is less than 10 in the metrics dictionary for that id. I can't seem to find a elegant way to do this at all and it's driving me nuts

Irish in Vancouver, what's new?

 

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, Shally said:

I want to update the 'results' dictionary with where the 'decision' : 'Failed' if count is less than 10 in the metrics dictionary for that id. I can't seem to find a elegant way to do this at all and it's driving me nuts

I've found that, generally, if a solution is not elegant just using basic data structures, it means that there is a new object definition hiding somewhere.

Your problem statement is a little vague, can you elaborate on what exactly you are trying to do?

ENCRYPTION IS NOT A CRIME

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, straight_stewie said:

Your problem statement is a little vague, can you elaborate on what exactly you are trying to do?

In the sample JSON i gave, I essentially want results to look like this after:
 

results = [
	{'id': '1', 'message': 'Queue does not have minimum required number of members. Required at least 5 but found 4.', 'decision': 'Failed'},
	{'id': '2', 'message': 'Less than 10 length', 'decision': 'Failed'}
]

So it updated id:2 because id:2 in the metrics dictionary had a count of 0, which is less than 10

 

Irish in Vancouver, what's new?

 

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, straight_stewie said:

I've found that, generally, if a solution is not elegant just using basic data structures, it means that there is a new object definition hiding somewhere.

Your problem statement is a little vague, can you elaborate on what exactly you are trying to do?

completely agree. 

 

 

7 hours ago, Shally said:

Hey guys,

So I have two dictionaries that look like this:
 

I want to update the 'results' dictionary with where the 'decision' : 'Failed' if count is less than 10 in the metrics dictionary for that id. I can't seem to find a elegant way to do this at all and it's driving me nuts

 

It would probably be better to generate the results from the metrics than to update the results from the metrics. 

create a function that takes your metrics, loops and generates the results list.

If you have control of the metrics i would get rid of the data list and just have the metrics list as looping over one list 'metrics' is better than having to loop data and then metrics

                     ¸„»°'´¸„»°'´ Vorticalbox `'°«„¸`'°«„¸
`'°«„¸¸„»°'´¸„»°'´`'°«„¸Scientia Potentia est  ¸„»°'´`'°«„¸`'°«„¸¸„»°'´

Link to comment
Share on other sites

Link to post
Share on other sites

I'm not going to ask why the data structure is so goshdarn ugly, I don't want to know, but here's my solution

 

def update():
	for d in results:
		if d["decision"] == "":
			d["decision"] = "Failed" if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10 else ""

...if you don't want to change the value of decision at all if it's 10 or over, do this:

def update():
	for d in results:
		if d["decision"] == "":
			if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10:
				d["decision"] = "Failed"

 

The way that lists and dictionaries are nested within eachother makes this difficult and ugly, so there really isn't a good way to do this specific tasks, but what you were looking for is casting the id string to an integer and subtracting one to get the corresponding id. This obviously doesn't work if the list isn't in order, and if you can't garuntee that, you'd need something more like this:

 

def update():
	for d in results:
		if d["decision"] == "":
			for i in metrics["results"]:
				if i["group"]["id"] == d["id"]:
					if i["data"][0]["metrics"][0]["results"]["count"] < 10:
						d["decision"] = "Failed"

Feel free to contact me if you have any questions~

 

(also first post meow)

Link to comment
Share on other sites

Link to post
Share on other sites

First off, i would suggest you clarify your naming scheme; you use "metrics" twice, "results" twice, and have another variable named "result".  Makes it harder for you to keep track of in your head, and really, really difficult to discuss with others.

 

I would suggest that either for the metrics or the results dictionary, rather than have an array of objects that contains a key with the id, you make one of them a dictionary, where the key is the id value.

 

i.e. instead of this

results = [
	{'id': '1', 'message': 'Queue does not have minimum required number of members. Required at least 5 but found 4.', 'decision': 'Failed'},
	{'id': '2', 'message': '', 'decision': ''}
]

Do this

results = {
	'1':{'message': 'Queue does not have minimum required number of members. Required at least 5 but found 4.', 'decision': 'Failed'},
	'2':{'message': '', 'decision': ''}
}

That way you can do a lookup based on the id value in another dictionary, rather than having to loop over every single result, which also results in your code being much more scalable.

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

16 hours ago, EnternodeCS said:

I'm not going to ask why the data structure is so goshdarn ugly, I don't want to know, but here's my solution

 


def update():
	for d in results:
		if d["decision"] == "":
			d["decision"] = "Failed" if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10 else ""

...if you don't want to change the value of decision at all if it's 10 or over, do this:


def update():
	for d in results:
		if d["decision"] == "":
			if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10:
				d["decision"] = "Failed"

 

The way that lists and dictionaries are nested within eachother makes this difficult and ugly, so there really isn't a good way to do this specific tasks, but what you were looking for is casting the id string to an integer and subtracting one to get the corresponding id. This obviously doesn't work if the list isn't in order, and if you can't garuntee that, you'd need something more like this:

 


def update():
	for d in results:
		if d["decision"] == "":
			for i in metrics["results"]:
				if i["group"]["id"] == d["id"]:
					if i["data"][0]["metrics"][0]["results"]["count"] < 10:
						d["decision"] = "Failed"

Feel free to contact me if you have any questions~

 

(also first post meow)

I actually started doing this solution too and hated it so much i stopped and went back to doing work XD

congrats on first post

                     ¸„»°'´¸„»°'´ Vorticalbox `'°«„¸`'°«„¸
`'°«„¸¸„»°'´¸„»°'´`'°«„¸Scientia Potentia est  ¸„»°'´`'°«„¸`'°«„¸¸„»°'´

Link to comment
Share on other sites

Link to post
Share on other sites

23 hours ago, EnternodeCS said:

I'm not going to ask why the data structure is so goshdarn ugly, I don't want to know, but here's my solution

 


def update():
	for d in results:
		if d["decision"] == "":
			d["decision"] = "Failed" if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10 else ""

...if you don't want to change the value of decision at all if it's 10 or over, do this:


def update():
	for d in results:
		if d["decision"] == "":
			if metrics["results"][int(d["id"]) - 1]["data"][0]["metrics"][0]["results"]["count"] < 10:
				d["decision"] = "Failed"

 

The way that lists and dictionaries are nested within eachother makes this difficult and ugly, so there really isn't a good way to do this specific tasks, but what you were looking for is casting the id string to an integer and subtracting one to get the corresponding id. This obviously doesn't work if the list isn't in order, and if you can't garuntee that, you'd need something more like this:

 


def update():
	for d in results:
		if d["decision"] == "":
			for i in metrics["results"]:
				if i["group"]["id"] == d["id"]:
					if i["data"][0]["metrics"][0]["results"]["count"] < 10:
						d["decision"] = "Failed"

Feel free to contact me if you have any questions~

 

(also first post meow)

This is a great post because it is the solution, and by virtue of being so ugly proves the point previous posters made about the data structure being terrible.

This is the kind of thing that you write, and then a while later when you need to fix it you absolutely hate yourself for having done it in the first place.

 

I sometimes have to look at the code that I wrote when I started my job over 10 years ago. If any of it contains something like loop, conditional, loop, conditional I am not happy with my past self hahaha.

Link to comment
Share on other sites

Link to post
Share on other sites

56 minutes ago, maplepants said:

This is a great post because it is the solution, and by virtue of being so ugly proves the point previous posters made about the data structure being terrible.

This is the kind of thing that you write, and then a while later when you need to fix it you absolutely hate yourself for having done it in the first place.

 

I sometimes have to look at the code that I wrote when I started my job over 10 years ago. If any of it contains something like loop, conditional, loop, conditional I am not happy with my past self hahaha.

I do this too at my current job of 4 years. Back when node had only use got promises and everyone at my work used callbacks. 

 

There is some real nasty hacked together code that is still in production 

 

This thread perfectly shows the do it right the first time. 

                     ¸„»°'´¸„»°'´ Vorticalbox `'°«„¸`'°«„¸
`'°«„¸¸„»°'´¸„»°'´`'°«„¸Scientia Potentia est  ¸„»°'´`'°«„¸`'°«„¸¸„»°'´

Link to comment
Share on other sites

Link to post
Share on other sites

22 hours ago, vorticalbox said:

I do this too at my current job of 4 years. Back when node had only use got promises and everyone at my work used callbacks. 

 

There is some real nasty hacked together code that is still in production 

 

This thread perfectly shows the do it right the first time. 

As well as the need for documentation. Looking at the pile of hacks that is anybody’s early node code is good for a laugh if it’s documented, and good for a cry when it isn’t.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×