I wrote a nested dictionary program. The dictionary generates well but I would like every smaller dictionary to be printed in a new line.
import random
list_of_surname = ["Gates", "Bezos", "Buffett", "Zuckerberg", "Arnault",
"Page", "Sołowow", "Solorz"]
list_of_name = ["Bill", "Jeff", "Warren ", "Mark ", "Bernard", "Larry ",
"Michał", "Zygmunt"]
list_of_age = [73, 24, 35, 76, 64, 75, 86, 45]
list_of_profession = ["businessman", "chairman", "inventor", "pioneer",
"speculator", "programmer"]
def generator_of_random_nested_dictionary(number_of_dictionaries):
nested_dictionary = {f'person_{number_of_dictionaries}' :
{"surname":random.choice(list_of_surname),
"name":random.choice(list_of_name),
"age":random.choice(list_of_age),
"profession":random.choice(list_of_profession)}
for number_of_dictionaries in range (1,number_of_dictionaries+1)}
print("")
print ([(x,y)for x,y in nested_dictionary.items()],sep="\n")
print("")
'''
print((for key,values in nested_dictionary,sep="\n"))
'''
generator_of_random_nested_dictionary(3)
this is my output:
[('person_1', {'surname': 'Arnault', 'name': 'Larry ', 'age': 24, 'profession': 'inventor'}), ('person_2', {'surname': 'Arnault', 'name': 'Larry ', 'age': 35, 'profession': 'businessman'}), ('person_3', {'surname': 'Solorz', 'name': 'Michał', 'age': 76, 'profession': 'pioneer'})]
output is good but how to modify the print function so that each smaller dictionary is displayed in a new line? I would like to have output in this form:
[('person_1', {'surname': 'Arnault', 'name': 'Larry ', 'age': 24, 'profession': 'inventor'}),
('person_2', {'surname': 'Arnault', 'name': 'Larry ', 'age': 35, 'profession': 'businessman'}),
('person_3', {'surname': 'Solorz', 'name': 'Michał', 'age': 76, 'profession': 'pioneer'})]
Passing a list to print isn't doing what you want:
print ([(x,y)for x,y in nested_dictionary.items()],sep="\n")
To use the sep argument to print, you need to pass the elements of this list as separate arguments, which we can do with the * operator:
print (*[(x,y)for x,y in nested_dictionary.items()],sep="\n")
importing the pprint module and changing the line to this:
pprint.pprint([(x,y)for x,y in nested_dictionary.items()], width=100)
Did the work for me.
Related
I am trying to find an element in a list, how can I do that? This is what I wrote:
user_list = [
{'name': 'Alizom_12',
'gender': 'f',
'age': 34,
'active_day': 170},
{'name': 'Xzt4f',
'gender': None,
'age': None,
'active_day': 1152},
{'name': 'TomZ',
'gender': 'm',
'age': 24,
'active_day': 15},
{'name': 'Zxd975',
'gender': None,
'age': 44,
'active_day': 752},
]
def find_user(user_name):
for items in user_list:
if user_name == 'name':
print(user_name+" exists")
else:
print(user_name+" does not exists")
when I print the following I want it to find the user:
find_user('Alizom_12')
You're close. You need to get the value in the dictionary
if user_name == items['name']:
user_list = [
{'name': 'Alizom_12',
'gender': 'f',
'age': 34,
'active_day': 170},
{'name': 'Xzt4f',
'gender': None,
'age': None,
'active_day': 1152},
{'name': 'TomZ',
'gender': 'm',
'age': 24,
'active_day': 15},
{'name': 'Zxd975',
'gender': None,
'age': 44,
'active_day': 752},
]
def find_user(user_name):
userExists = False
for items in user_list:
for key, value in items.items():
if key == 'name' and value == user_name:
userExists = True
if userExists is True:
print(user_name+" exists")
else:
print(user_name+" does not exists")
find_user('Alizom_12')
There are more than one places that your code has to be fixed:
Let's try to use the code snippet to point out them one by one.
First you can find the user_name by go through each dict. and the key name, secondly, it's better to return and not print.
Lastly, the last print should be out side of the for-loop, otherwise, you will get many repeated not found messages...
def find_user(user_name):
for items in user_list:
if items['name'] == user_name:
return f'{user_name} exists. '
#return items # will return this user's dict. (all info) *You have to comment prev. statement first. and uncomment this
return f'{user_name} - does not exists'
print(find_user('Alizom_12')) # Alizom_12 exists.
print(find_user('John Doe')) # John Doe - does not exists
I have the following list:
list_dict = [
{'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
{'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
{'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
{'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': []}
]
I would like to add a hobby to R2:
for i in range(len(list_dict)):
people = list_dict[i]
if people['name'] == 'R2':
people['hobbies'] = ['lubrication']
print(list_dict)
I got what I was expecting but as a newbie I'd like to learn a few easy tricks to make it shorter.
I'd express as:
people = {person['name']: person for person in list_dict}
people['R2']['hobbies'] += ['lubrication'] # reads nicely as "add a hobby to R2"
For all those hung up on the academic concern of "potential people with same name", although the "Leetcode answer" would be:
for person in list_dict:
if person['name'] == 'R2':
person['hobbies'] += ['lubrication']
But in practice, remodeling data to have & use primary keys is probably what you want in most cases.
You can just iterate over the list and condense the if statement:
for person in list_dict:
person['hobbies'] = ['lubrication'] if person['name'] == 'R2' else person['hobbies']
There are some other answers here but in my eyes they don't really help a newbie seeking to shorten his code. I don't suggest to use the below proposed shortening except the looping over items in list instead of using indices, but to give here an answer with some maybe worth to know 'tricks' (you can have more than one name pointing to same variable/object, you can iterate directly over items of a list instead using indices) to a newbie here a shortened version of the code:
for p in l:
if p[n]=='R2': p[h]=['lubrication']
print(l)
and below all of the code using the proposed shortening with comments pointing out the 'tricks':
list_dict = [
{'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
{'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
{'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
{'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': []},
{'name': 'R2', 'age': 15, 'country': 'Alduin', 'hobbies': []}
]
l = list_dict; n='name'; h='hobbies'
# I would like to add a hobby to R2:
"""
for i in range(len(list_dict)):
people = list_dict[i]
if people['name'] == 'R2':
people['hobbies'] = ['lubrication']
"""
# I got what I was expecting but as a newbie I'd like to learn a few
# easy tricks to make it shorter:
for p in l: # loop over items in list instead of using indices
if p[n]=='R2': p[h]=['lubrication'] # use short variable names
# ^-- give --^ long string constants short names
print(l)
there is no need to loop over the lenght, you can loop through the list and you can condense with a one-liner if statement
#!usr/bin/python3
from pprint import pprint
for person in list_dict:
person['hobbies'].append('lubrification') if person['name'] == 'R2' else ...
pprint(list_dict)
>>> [
{'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
{'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
{'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
{'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': ["lubrification"]}
]
you can also do this with a comprehension:
[person['hobbies'].append('lubrification') for person in list_dict if person['name']]
But, if you just want to change one, you can use this code:
m = next(i for i,person in enumerate(list_dict) if person["name"]=="R2")
list_dict[m]["hobbies"].append("lubrification")
This question already has answers here:
Find the index of a dict within a list, by matching the dict's value
(12 answers)
Closed 3 years ago.
Say I have the following list of dicts:
dicts = [
{'name': "Tom", 'age': 20, 'height': 1.8},
{'name': "Isa", 'age': 31, 'height': 1.5},
... ]
I'd like to replace the age of a given person with a given value.
def replace_age(person, age):
dicts[?]['age'] = age
replace_age("Tom", 45)
Assuming that name is unique, what's the most elegant way to go about this?
In a golden world: dicts[name=person]['age'] = age
Not a duplicate of Find the index of a dict within a list, by matching the dict's value: I'm looking to change the value, not get the index. And Tom is a pretty common name.
this is a variant:
def replace_age(person, age):
try:
dct = next(item for item in dicts if item["name"] == person)
except StopIteration:
# person not found
# here you could print a message or raise an error...
return
dct["age"] = age
this will only work if the names are unique. if they are not only the first occurrence will be replaced.
since the name is unique you can change your data structure where you keep your data to achieve your task efficiently:
efficient_dict = {e['name']: {'age' : e.get('age'), 'height': e.get('height')} for e in dicts}
def replace_age(person, age):
if person in efficient_dict:
efficient_dict[person]['age'] = age
Here's my version
dictionaries = [
{'name': "Tom", 'age': 20, 'height': 1.8},
{'name': "Isa", 'age': 31, 'height': 1.5}
]
def change_dict_person_age(dictionaries, person, age):
for dictionary in dictionaries:
if dictionary['name'] == person:
dictionary['age'] = age
# Uncomment the following line if you want to stop at the 1st
# match. Leave it as is if you want to modify all occurrences.
#break
change_dict_person_age(dictionaries, "Tom", 40)
print(dictionaries)
#[{'name': 'Tom', 'age': 40, 'height': 1.8}, {'name': 'Isa', 'age': 31, 'height': 1.5}]
I also wrote a more generic version for broader user:
dictionaries = [
{'name': "Tom", 'age': 20, 'height': 1.8},
{'name': "Isa", 'age': 31, 'height': 1.5}
]
def change_dict(dictionaries, key_to_check, value_to_match, key_to_change, value_to_change):
for dictionary in dictionaries:
if dictionary[key_to_check] == value_to_match:
dictionary[key_to_change] = value_to_change
# Uncomment the following line if you want to stop at the 1st
# match. Leave it as is if you want to modify all occurrences.
#break
change_dict(dictionaries, "name", "Tom", "age", 50)
print(dictionaries)
#[{'name': 'Tom', 'age': 50, 'height': 1.8}, {'name': 'Isa', 'age': 31, 'height': 1.5}]
File1.py
john = {'fullname':'John Wick', 'Age': 35 , 'job':'Hitman'}
mark = {'fullname':'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'}
Will = {'fullname':'Will smith', 'Age': 45, 'job': 'Actor'}
so on... and many more names
So my question is how do I access the values, lets say I want to know the age of a person by giving the person's name?
File2.py
from File1.py import *
#what should the code be to access the age
#lets say I write 'john', I want to get his age
print john['Age'] # this is not how i want to access it
#
#any other way or methods ??
#
user_input=raw_input("enter a Name: ")
# user_input contains the name of the person I want to get the Age of
You can use a nested dictionary to pass the person's name to the dictionary and then access the age via the key "Age":
john = {'fullname':'John Wick', 'Age': 35 , 'job':'Hitman'}
mark = {'fullname':'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'}
Will = {'fullname':'Will smith', 'Age': 45, 'job': 'Actor'}
new_data = {"John":john, "Mark":mark, "Will":Will}
print(new_data["John"]["Age"])
Output:
35
Edit: Without a nested dictionary, you can try this:
john = {'fullname':'John Wick', 'Age': 35 , 'job':'Hitman'}
mark = {'fullname':'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'}
Will = {'fullname':'Will smith', 'Age': 45, 'job': 'Actor'}
user_input=raw_input("enter a Name: ")
final_age = [b["Age"] for a, b in globals().items() if a == user_input][0]
Output:
35
First of all in my opinion you should NOT do it like this. #Ajax1234 offers a much better solution, but to ask your question:
import File1
name = input('>>> Name: ')
print(getattr(File1, name)['Age']) # 35
Does it
You can use get function in dictionary
print(john.get('age' , 0))
get take two parameter first the key then the default value to load if key not found
You can use the built-in globals function. From documentation (emphasis mine):
Return a dictionary representing the current global symbol table. This is always the dictionary of the current module (inside a function or method, this is the module where it is defined, not the module from which it is called).
Edit:
As you are using separate files, you can create a function in the file File1.py that accepts the dictionary name and returns the appropriate value using the globals() function.
Usage:
File1.py
john = {'fullname':'John Wick', 'Age': 35 , 'job':'Hitman'}
mark = {'fullname':'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'}
Will = {'fullname':'Will smith', 'Age': 45, 'job': 'Actor'}
def get_age(person):
return globals()[person]['Age']
File2.py
import File1
person = input('Enter name:')
print(File1.get_age(person))
I don't fully understand why you are saving each of these dicts into a separate variable instead of just using a nested dict like
persons = {
'john': {'fullname': 'John Wick', 'Age': 35, 'job': 'Hitman'},
'mark': {'fullname': 'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'},
'will': {'fullname': 'Will Smith', 'Age': 45, 'job': 'Actor'}
}
with which you could use user input to access the persons dict's keys,
if you really want to name your variables based on their values (which does not make much sense to me since it's not really variable after), you can use Python's globals() and locals() function.
file1.py
john = {'fullname': 'John Wick', 'Age': 35, 'job': 'Hitman'}
mark = {'fullname': 'Mark Zuckerberg', 'Age': 30, 'job': 'Developer'},
will = {'fullname': 'Will Smith', 'Age': 45, 'job': 'Actor'}
file2.py
from file1 import *
name = raw_input('Please enter a name:')
global_vars = globals()
print(global_vars[name])
But still, since you could just use a nested dict I see no single valid reason to use globals() for this use case at all. Just declare your dicts under keys in another dict and you should be just fine.
Next to a nested dictionary you can also use an import alias to make you code cleaner.
import File1 as employees
name = raw_input("Enter name:")
print(getattr(employees, name)['Age'])
How can I remove empty dict from list of dict as,
{
"ages":[{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
]
}
I am beginner to python.
Thanks in advance.
Try this
In [50]: mydict = {
....: "ages":[{"age":25,"job":"teacher"},
....: {},{},
....: {"age":35,"job":"clerk"}
....: ]
....: }
In [51]: mydict = {"ages":[i for i in mydict["ages"] if i]}
In [52]: mydict
Out[52]: {'ages': [{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]}
OR simply use filter
>>>mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
>>>filter(None, mylist)
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]
So in your dict, apply it as
{
"ages":filter(None, [{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
])
}
There's a even simpler and more intuitive way than filter, and it works in Python 2 and Python 3:
You can do a "truth value testing" on a dict to test if it's empty or not:
>>> foo = {}
>>> if foo:
... print(foo)
...
>>>
>>> bar = {'key':'value'}
>>> if bar:
... print(bar)
...
{'key':'value'}
Therefore you can iterate over mylist and test for empty dicts with an if-statement:
>>> mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
>>> [i for i in mylist if i]
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]
If you are using Python 3, simply do:
list(filter(None, your_list_name))
This removes all empty dicts from your list.
This while loop will keep looping while there's a {} in the list and remove each one until there's none left.
while {} in dictList:
dictList.remove({})
You may try the following function:
def trimmer(data):
if type(data) is dict:
new_data = {}
for key in data:
if data[key]:
new_data[key] = trimmer(data[key])
return new_data
elif type(data) is list:
new_data = []
for index in range(len(data)):
if data[index]:
new_data.append(trimmer(data[index]))
return new_data
else:
return data
This will trim
{
"ages":[{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
]
}
and even
{'ages': [
{'age': 25, 'job': 'teacher', 'empty_four': []},
[], {},
{'age': 35, 'job': 'clerk', 'empty_five': []}],
'empty_one': [], 'empty_two': '',
'empty_three': {}
}
to this:
{'ages': [{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]}
You can also try this
mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
mylist=[i for i in mylist if i]
print(mylist)
Output:
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]