Python: How do I iterate over more than 2 dictionaries? - python

Not really sure what I'm doing wrong here. I thought the zip method would work to check if a value is in multiple lists? What I'd want it to do is check to see if that value is in any of those dictionaries, and if so, to print its key, but if not, then print only one string of ('Not in Any Dictionary'). This method prints 40 of them for some reason with the real dictionaries.
MLB_Teams = {1: 'New York Yankees', 2: 'Pittsburgh Pirates'}
NBA_Teams = {1: 'Houston Rockets', 2: 'Brooklyn Nets'}
NFL_Teams = {1: 'Philadelphia Eagles', 2: 'Detroit Lions'}
for (key,value), (key,value), (key, value) in zip(MLB_Teams.items(), NBA_Teams.items(), NFL_Teams.items()):
reply = 'Houston Rockets'
if reply == value:
print(key)
else:
print('Not In Any Dictionary')

I think you can do it in a very simple way:
MLB_Teams = {1: 'New York Yankees', 2: 'Pittsburgh Pirates'}
NBA_Teams = {1: 'Houston Rockets', 2: 'Brooklyn Nets'}
NFL_Teams = {1: 'Philadelphia Eagles', 2: 'Detroit Lions'}
v = 'Philadelphia Eagles'
def find_in_dict(val, d):
for k, v in d.items():
if v == val:
print(k)
return True
for dd in (MLB_Teams, NBA_Teams, NFL_Teams):
if find_in_dict(v, dd):
break
else:
print('Not In Any Dictionary')

The issue lies in how you've reused the variable names for key and value. Add a print statement to see the effect.
for (key,value), (key,value), (key, value) in zip(MLB_Teams.items(), NBA_Teams.items(), NFL_Teams.items()):
print(value) #added
reply = 'Houston Rockets'
if reply == value:
print(key)
else:
print('Not In Any Dictionary')
#output
Philadelphia Eagles
Not In Any Dictionary
Detroit Lions
Not In Any Dictionary
The variables key and value get reassigned to the last entry in the tuple.
You can use the zip just fine if you handle unpacking later.
MLB_Teams = {1: 'New York Yankees', 2: 'Pittsburgh Pirates'}
NBA_Teams = {1: 'Houston Rockets', 2: 'Brooklyn Nets'}
NFL_Teams = {1: 'Philadelphia Eagles', 2: 'Detroit Lions'}
reply = 'Houston Rockets'
for tups in zip(MLB_Teams.items(), NBA_Teams.items(), NFL_Teams.items()):
if any(reply == val for key,val in tups):
print(tups[0][0]) #key
else:
print('Not In Any Dictionary')
#output
1
Not In Any Dictionary

Related

loop through nested dictionary in python and display key value pair

i am a beginner in python i and i came up this problem and i cant seem to solve it.I have the following dictionary
stats = {1: {"Player": "Derrick Henry", "yards": 870, "TD": 9}, 2: {"Player": "Nick Chubb", "Yards": 841, "TD": 10}, 3: {"Player": "Saquon Barkley", "Yards": 779, "TD": 5}}
I want to loop through a dictionary and display the values as shown below
Player1
Player=Derrick Henry
yards=870
TD=9
player 2
Player=Nnikki Chubb
yards=770
TD=10
player3
Player=Nikki Chubb
yards=770
TD=10
i tried the following code
stats = {1: {"Player": "Derrick Henry", "Yards": 870, "TD": 9}, 2: {"Player": "Nick Chubb", "Yards": 841, "TD": 10}, 3: {"Player": "Saquon Barkley", "Yards": 779, "TD": 5}}
for key, value in stats.items():
print(value)
for x, y,z in value.items():
print("Player {}".format(key))
#IF Player
if x == "Player":
print("Player = {}".format(x))
#IF YARDS
if y == "Yards":
print("Yards = {}".format(y))
#IF YARDS
if z == "TD":
print("yards = {}".format(y))
Any help will be appreciated.Thank you
Don't you see here the useless logic : if a variable is something, you write manualmy that thing in a string, just use it directly
if x == "Player":
print("Player = {}".format(x))
if y == "Yards":
print("Yards = {}".format(y))
if z == "TD":
print("TD = {}".format(y))
Also you did well use .items first time, but misuses it the second time, it iterate over pair, so it'll always yields 2 variable , not 3
for key, props in stats.items():
print(f"Player{key}")
for prop_key, prop_value in props.items():
print(f"{prop_key}={prop_value}")
You kinda haven't really decided yet, if you want to iterate over the nested dict or not. To iterate over it, check azro's answer. But what you are attempting is not iterating, so you can just write:
print("Player = {}".format(value["Player"]))
print("Yards = {}".format(value["Yards"]))
print("TD = {}".format(value["TD"]))
Or, as the print statements are all the same, you could loop over the keys you want to print:
for key in ["Player", "Yards", "TD"]:
print("{} = {}".format(key, value[key])

Python: JSON, Problem with list of dictionaries, certain value into my dictionary

So, I have been thinking of this for a long time now, but can't seem to get it right. So I have to use a JSON file to make a dictionary where I get the keys: 'userIds' and the value 'completed' tasks in a dictionary. The best I got was the answer: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 90}, with this code under:
import requests
response1 = requests.get("https://jsonplaceholder.typicode.com/todos")
data1 = response1.json()
dict1 = {}
keys = []
values = []
for user in data1:
if user not in keys or values:
keys.append(user['userId'])
values.append(0)
for key, value in zip(keys, values):
dict1[key] = value
for user in data1:
if user['completed'] == True:
dict1[key] += 1
print(dict1)
but I feel like this next code would be closer, but I can't figure out how to get it to work
import requests
response1 = requests.get("https://jsonplaceholder.typicode.com/todos")
data1 = response1.json()
dict1 = {}
keys = []
values = []
for user in data1:
if user not in keys or values:
keys.append(user['userId'])
values.append(0)
for key, value in zip(keys, values):
dict1[key] = value
for key, value in data1.items():
if user['completed'] == True:
dict1[key].update += 1
print(dict1)
After this, the output is just
" line 24, in
for key, value in data1.items():
AttributeError: 'list' object has no attribute 'items'",
And I do get why, I don't jsut know how to continue from here.
Would really appreciate anyones help, with this obnoxious task.
can u try this ?
import requests
response1 = requests.get("https://jsonplaceholder.typicode.com/todos")
data1 = response1.json()
dict1 = {}
keys = []
values = []
for user in data1:
if user not in keys or values:
keys.append(user['userId'])
values.append(0)
for key, value in zip(keys, values):
dict1[key] = value
print(data1)
for x in data1:
for key, value in x.items():
if key =="completed" :
if value == True:
dict1[x["userId"]] += 1
print(dict1)
Try with this approach:
import json
import requests
response1 = requests.get("https://jsonplaceholder.typicode.com/todos")
data1 = response1.json()
dict1 = {}
for user in data1:
uid = user['userId']
if user['completed']:
dict1[uid] = dict1.get(uid, 0) + 1
elif uid not in dict1:
dict1[uid] = 0
print(dict1)
print(json.dumps(dict1, indent=2))
If needed, you can also simplify the above logic using defaultdict, and leverage the fact that bool is a subclass of int:
from collections import defaultdict
dict1 = defaultdict(int)
for user in data1:
dict1[user['userId']] += user['completed']
Output:
{1: 11, 2: 8, 3: 7, 4: 6, 5: 12, 6: 6, 7: 9, 8: 11, 9: 8, 10: 12}
{
"1": 11,
"2": 8,
"3": 7,
"4": 6,
"5": 12,
"6": 6,
"7": 9,
"8": 11,
"9": 8,
"10": 12
}

how to check values of dictionary in Python?

d1 = {'name': 'Sagar','age': 25}
d2 = {'name': 'Sassdr', 'age':122}
d3 = {'name': 'Saga23weer', 'age':123344}
d4 = {'name': '2133Sagar', 'age':14322}
ch = input("Enter your value: ")
How can I search inputted value from these dictionaries?
and if found value then it returns Found else return not found.
Why are a search value in different dictionary rather than in one??
Try this
merge all dictionary in one
d5 = {**d1, **d2, **d3, **d4}
and then check
if ch in d5 .values():
print "Found"
else:
print "Not Found"
Make a list of dictionaries and search in it:
d1 = {'name': 'Sagar','age': 25}
d2 = {'name': 'Sassdr', 'age':122}
d3 = {'name': 'Saga23weer', 'age':123344}
d4 = {'name': '2133Sagar', 'age':14322}
d = [d1,d2,d3,d4]
def check(ch):
for entry in d:
if entry["name"] == ch:
return("found")
return ("Not found")
while True:
ch = input("Enter your value: ")
if ch == "stop":
break
print(check(ch))
Output:
>>>
Enter your value: Sagar
found
Enter your value: Someone
Not found
Enter your value: 2133Sagar
found
Enter your value: stop
The effect you want is called key swap. This snippet is the implementation:
def keyswap(yourdict):
cache = {}
for i in yourdict.keys():
cache[yourdict[i]] = i
for i in cache.keys():
yourdict[i] = cache[i]
del cache
It keyswaps inplace.
You can use following code
Python2
def IsFound():
list_dict = [d1, d2, d3, d4]
values_list = []
for each in list_dict:
values_list += each.values()
ch = input('enter your value')
if ch in values_list:
return 'Found'
else:
return 'Not Found'
Python3
def IsFound():
dict = {**d1, **d2, **d3, **d4}
ch = input('enter your value')
if ch in dict.values():
return 'Found'
else:
return 'Not Found'
you need to do:
get the values of dict;
search all dicts;
mark result as "Found" if matches.
for step 1:
dict.values()
for step 2:
there's many way to combine all dicts, as everybody gives.
you can pick all values first to set a new list, then search if your input matches like this:
# combine all dicts
d = d1.values() + d2.values() +d3.values() + d4.values()
# judge if matches
if ch in d:
# do something
hope this code can release your confuse.

Python program using `defaultdicts` doesn't work as expected

Expected result:
main_dict = {
'a':
{ 0: 'Letter a',
1: 'Letter a',
2: 'Letter a',},
'b':
{ 0: 'Letter b',
1: 'Letter b',
2: 'Letter b',},
'c':
{ 0: 'Letter c',
1: 'Letter c',
2: 'Letter c',}
}
My program, version 1; the expected results is the output.
# my_program.py
def fill_dict(a_dict, a_key):
if not a_dict.has_key(a_key):
a_dict[a_key] = {}
for i in xrange(3):
a_dict[a_key][i] = 'Letter {}'.format(a_key)
def main():
main_dict = {}
a_list = ['a', 'b', 'c']
for item in a_list:
fill_dict(main_dict, item)
if __name__ == '__main__':
main()
Refactored program using defaultdicts; result is main_dict = {}.
# defaultdict_test.py
import collections
def fill_dict(a_dict, a_key):
a_dict = collections.defaultdict(dict)
for i in xrange(3):
a_dict[a_key][i] = 'Letter {}'.format(a_key)
def main():
main_dict = {}
a_list = ['a', 'b', 'c']
for item in a_list:
fill_dict(main_dict, item)
if __name__ == '__main__':
main()
Any pointers on what I'm doing wrong? Thanks.
You are passing main_dict into fill_dict, then assigning a new defaultdict to the local variable a_dict. You never pass that value back out.
In your program that works, you don't reassign the local, so when you call methods on a_dict, you are modifying the value passed in, which is the main_dict value from main.
This distinction, between reassigning, and mutating with methods, is subtle but important. This article has more on names, values, and their interactions: Facts and myths about Python names and values.
Pointers:
Use in vs has_key in your first version. The method has_key has been depricated and removed in Python 3
Remove a_dict = collections.defaultdict(dict) from fill_dict
Change main_dict = {} to main_dict = collections.defaultdict(dict) in main
Done!
import collections
def fill_dict(a_dict, a_key):
for i in xrange(3):
a_dict[a_key][i] = 'Letter {}'.format(a_key)
def main():
main_dict = collections.defaultdict(dict)
a_list = ['a', 'b', 'c']
for item in a_list:
fill_dict(main_dict, item)
Final pointer: Get to know list, set and dict comprehensions. You can do this data structure in a single line:
>>> {c:{i: 'Letter {}'.format(c) for i in range(3)} for c in 'abc'}
{'a': {0: 'Letter a', 1: 'Letter a', 2: 'Letter a'}, 'c': {0: 'Letter c', 1: 'Letter c', 2: 'Letter c'}, 'b': {0: 'Letter b', 1: 'Letter b', 2: 'Letter b'}}
If you look at it -- it is almost a version of what you have as your desired result if you format it that way:
dict_you_want={
c:
{ i: 'Letter {}'.format(c)
for i in range(3) } # ,
for c in 'abc'
}
which will execute just as I have it there...

Modifying nested dictionaries

Given this two dicts:
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}
Firstly, I want to check if empty.keys() == full.keys() if it holds, I want to replace the empty values with corresponding value from full dictionary. It ought to result in:
not_empty = {'151': {'1': '3.4', '0': '3.6', '2': '2.30'}}
My solution so far: I thought I would identify all the keys with empty values using regex, but for whatever reason my code so far, produces an empty dict {}.
import re
find_empty = re.findall("'(\d)':\s'empty'", str(empty))[0]
if empty.keys() == full.keys():
k = empty.values()[0].keys()
v = empty.values()[0].values()
print {k:v for k,v in empty.values()[0].iteritems()\
if empty.values()[0][find_empty] != 'empty'}
I hoped it can output {'151': {'2': '2.30'}} for a good starting point. Anyway, I guess there exists more clean solution then regex for this task so any hints are welcomed!
Regex is not the right tool for this job. I would suggest a recursive approach like the following.
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}
def repl(a, b):
clean = {}
for k, v in a.items():
# This is the case where we want to replace what we have in b if we have something. Just in case, use the dict.get method and provide a default.
if v == 'empty':
clean[k] = b.get(k, 'Not there')
# If the value is another dict, then call this function with the value, and put the return as the value for our current key
elif isinstance(v, dict):
v_clean = repl(v, b.get(k, {}))
clean[k] = v_clean
# The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
else:
clean[k] = v
# Finally, return the cleaned up dictionary.
return clean
print repl(empty, full)
OUTPUT
{'151': {'1': 3.4, '0': 3.6, '2': '2.30'}}
EDIT I am not sure if this takes care of all of your cases, but it probably worth a look anyway.
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30', '8': ['empty', 'empty', 5, {"foo2": "bar2", "1": "empty"}]}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2, '8': ['foo', 'bar', 'baz', {"foo3": "bar3", "1": "2"}]}}
def repl(a, b):
if isinstance(a, dict) and isinstance(b, dict):
clean = {}
for k, v in a.items():
# This is the case where we want to replace what we have in b if we have something. Just in case, use the dict.get method and provide a default.
if v == 'empty':
clean[k] = b.get(k, 'Not there')
# If the value is another dict, then call this function with the value, and put the return as the value for our current key
elif isinstance(v, dict):
v_clean = repl(v, b.get(k, {}))
clean[k] = v_clean
# The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
elif isinstance(v, list):
v_clean = repl(v, b.get(k, []))
clean[k] = v_clean
else:
clean[k] = v
# Finally, return the cleaned up dictionary.
elif isinstance(a, list) and isinstance(b, list):
clean = []
for item_a, item_b in zip(a, b):
if item_a == 'empty':
clean.append(item_b)
elif isinstance(item_a, dict):
clean_a = repl(item_a, item_b)
clean.append(clean_a)
else:
clean.append(item_a)
return clean
print repl(empty, full)
OUTPUT
{'151': {'1': 3.4, '0': 3.6, '2': '2.30', '8': ['foo', 'bar', 5, {'1': '2', 'foo2': 'bar2'}]}}

Categories

Resources