Selecting dictionary nested in a list by index - python

Here is am example of the list:
{'Item': 'milk', 'Price': '2.0', 'Quantity': '2'}, {'Item': 'egg', 'Price': '12.0', 'Quantity': '1'}]
Here is my code:
def edit_items(info):
xy = info
print('Index | Orders')
for x in enumerate(xy):
print('\n')
print(x)
choice = int(input('Which entry would you like to edit? Choose by index. :'))
print(x[choice])
Id like the user to able to chose an entry by index, and allow them to edit information inside the dictionary.
So far my code prints out:
Index | Orders
(0, {'Item': 'milk', 'Price': '2.0', 'Quantity': '2'})
(1, {'Item': 'egg', 'Price': '12.0', 'Quantity': '1'})
But i have no idea how to choose one, assign It to a variable and carry out the ability to edit whats inside.
Cheers. Nalpak_

def edit_items(info):
xy = info
# to make multiple edits.
while True:
print('Index | Orders')
for x in range(len(xy)):
print(x,xy[x])
choice = int(input('Which entry would you like to edit?\nChoose by index: '))
print(xy[choice])
edit = input('What you want to edit: ') # Key val of dict
value = input("Enter: ") # Value for the specific key in dict
xy[choice][edit] = value
print('list updated.')
print(xy[choice])
more_edits = input('\nDo you want to make more edits?(y/n): ')
if more_edits == 'n':
break
edit_items(info)
this will help you make multiple edits.

If you want to edit an item in a dictionary, you can easily do it by accessing it by the key.
First, we set up the data
xy = [{'Item': 'milk', 'Price': '2.0', 'Quantity': '2'}, {'Item': 'egg', 'Price': '12.0', 'Quantity': '1'}]
Then if I understood you correctly, this edit_items method should do exactly what you need:
def edit_items(i):
name = input('Type in a new item name: ')
xy[i]['Item'] = name # 'Item' is the key.
Everything else is pretty much the same:
print('Index | Orders')
for x in enumerate(xy):
print('\n')
print(x)
choice = int(input('Which entry would you like to edit? Choose by index. :'))
print(xy[choice])
edit_items(choice)
print(xy)
If you want, you can also use input for getting a key (property) of an item you want to edit.

Related

Searching for a specific value within a list of dictionaries

I need to be able to print all instances of a name within the list of dictionaries. I can't seem to be able to print them in the desired format. It also doesn't work when it's in lowercase and the name is in uppercase.
def findContactsByName(name):
return [element for element in contacts if element['name'] == name]
def displayContactsByName(name):
print(findContactsByName(name))
if inp == 3:
print("Item 3 was selected: Find contact")
name = input("Enter name of contact to find: ")
displayContactsByName(name)
When the name 'Joe' was put in the output is:
[{'name': 'Joe', 'surname': ' Miceli', 'DOB': ' 25/06/2002', 'mobileNo': ' 79444425', 'locality': ' Zabbar'}, {'name': 'Joe', 'surname': 'Bruh', 'DOB': '12/12/2131', 'mobileNo': '77777777', 'locality': 'gozo'}]
When the name 'joe':
[]
Expected output:
name : Joe
surname : Miceli
DOB : 25/06/2002
mobileNo : 79444425
locality : Zabbar
name : Joe
surname : Bruh
DOB : 12/12/2131
mobileNo : 77777777
locality : gozo
Change the first function to:
def findContactsByName(name):
return [element for element in contacts if element['name'].lower() == name.lower()]
To account for the differences in uppercase and lowercase, I've just converted the name in the dictionary and the entered name to lowercase during the comparison part alone.
To be able to print it in the format that you've specified you could make a function for the same as follows:
def printResult(result):
for d in result:
print(f"name: {d['name']}")
print(f"surname: {d['surname']}")
print(f"DOB: {d['DOB']}")
print(f"mobileNo: {d['mobileNo']}")
print(f"locality: {d['locality']}")
print()
result=findContactsByName("joe")
printResult(result)
I modified your program. Now you don't have to worry about the case and the output formatting.
contacts = [{'name': 'Joe',
'surname': ' Miceli', 'DOB': ' 25/06/2002', 'mobileNo': ' 79444425', 'locality': ' Zabbar'},
{'name': 'Joe', 'surname': 'Bruh', 'DOB': '12/12/2131', 'mobileNo': '77777777', 'locality': 'gozo'}]
def findContactsByName(name):
return [element for element in contacts if element['name'].lower() == name.lower()]
def displayContactsByName(name):
for i in range(len(findContactsByName(name))):
for j in contacts[i]:
print('{}: {}'.format(j, contacts[i][j]))
print('\n')
displayContactsByName('Joe')
Case issue can be solved by setting each side of the comparison to UPPERCASE or LOWERCASE.
return [element for element in contacts if element['name'].upper() == name.upper()]
For the format of the print statement you could use the json module:
import json
print(json.dumps( findContactsByName(name), sort_keys=True, indent=4))

My search input functions works, but it only prints the last person's information in the list of dicts

I'm kind of new to python, and I need some help. I'm making an employee list menu. My list of dictionaries is:
person_infos = [ {'name': 'John Doe', 'age': '46', 'job position': 'Chair Builder', 'pay per hour': '14.96','date hired': '2/26/19'},
{'name': 'Phillip Waltertower', 'age': '19', 'job position': 'Sign Holder', 'pay per hour': '10','date hired': '5/9/19'},
{'name': 'Karen Johnson', 'age': '40', 'job position': 'Manager', 'pay per hour': '100','date hired': '9/10/01'},
{'name': 'Linda Bledsoe', 'age': '60', 'job position': 'CEO', 'pay per hour': '700', 'date hired': '8/24/99'},
{'name': 'Beto Aretz', 'age': '22', 'job position': 'Social Media Manager', 'pay per hour': '49','date hired': '2/18/12'}]
and my "search the list of dicts input function" is how the program is supposed to print the correct dictionary based on the name the user inputs:
def search_query(person_infos):
if answer == '3':
search_query = input('Who would you like to find: ')
they_are_found = False
location = None
for i, each_employee in enumerate(person_infos):
if each_employee['name'] == search_query:
they_are_found = True
location = i
if they_are_found:
print('Found: ', person_infos[location]['name'], person_infos[location]['job position'], person_infos[location]['date hired'], person_infos[location]['pay per hour'])
else:
print('Sorry, your search query is non-existent.')
and I also have this-
elif answer =='3':
person_infos = search_query(person_infos)
This seems like a step in the right direction, but for
search_query = input('Who would you like to find: ')
if I input of the names in person_infos, like "John Doe," it just prints the last dictionary's information (no matter which specific dictionary it is, the last one in the order will always be outputted) instead of John Doe's. in this case, it would only print "Beto Aretz's."
Can someone please help? It's something I've been struggling on for a while and it would be awesome.
I've researched so much and I could not find something with things that I either knew how to do, or were the input search.
Thanks,
LR
At first glance it looks like because your location=i is not indented inside your if statement so it is getting set to the latest i on each iteration of the for loop. Let me know if this helps.
def search_query(person_infos):
if answer == '3':
search_query = input('Who would you like to find: ')
they_are_found = False
location = None
for i, each_employee in enumerate(person_infos):
if each_employee['name'] == search_query:
they_are_found = True
location = i
if they_are_found:
print('Found: ', person_infos[location]['name'], person_infos[location]['job position'], person_infos[location]['date hired'], person_infos[location]['pay per hour'])
else:
print('Sorry, your search query is non-existent.')

Matching User 's Input With Nested Dictionary in Python3.7

I cannot seem to match the user input(num) to id_num to print out the individual license info. I want that when the user is prompted to enter the license number, the code should loop through the dictionary and find its match and print the info that matches the input.
I tried:
if num in driver_license[id_num]:
if num==id_num:
if num==int(id_num):
42456 :{'name': 'jill', 'ethnicity': 'hispanic','eye': 'yellow' ,'height': '6.1'},
44768 :{'name': 'cheroky', 'ethnicity': 'native','eye': 'green' ,'height': '6.7'},
32565 :{'name': 'valentina', 'ethnicity': 'european','eye': 'fair','height': '4.9'}}
print('\n')
print('- ' *45)
for id_num, id_info in driver_license.items():
num = int(input('Enter your driving license number: '))
print(f"Id number: {id_num}")
name=f"{id_info['name']}"
origin= f"{id_info ['ethnicity']}"
eye= f"{id_info['eye']}"
height=f"{id_info['height']}"
if num in driver_license[id_num]:
print(f'\nId number is:{num}')
print(f'Name: {name}')
print(f'Ethnicity: {origin}')
print(f'Eyes color: {eye}')
print(f'Height: {height}\n')
else:
print('Invalid ID')
There is no error but a mismatch of output than expected.
You don't need to loop through the dictionary.
You can instead use get(key, default) to get the entry from the driver_license dictionary using the input license number as the key. You can then set default to some value to handle the case where the key is not in the dict (here I used None).
driver_license = {
"42456" : {'name': 'jill', 'ethnicity': 'hispanic','eye': 'yellow' ,'height': '6.1'},
"44768" : {'name': 'cheroky', 'ethnicity': 'native','eye': 'green' ,'height': '6.7'},
"32565" : {'name': 'valentina', 'ethnicity': 'european','eye': 'fair','height': '4.9'}
}
id_num = input('Enter your driving license number: ')
# if user enters "32565"
id_info = driver_license.get(id_num, None)
# id_info would be:
# {'name': 'valentina', 'ethnicity': 'european','eye': 'fair','height': '4.9'}
if id_info:
print(f'\nId number is:{id_num }')
print(f'Name: {id_info["name"]}')
print(f'Ethnicity: {id_info["ethnicity"]}')
print(f'Eyes color: {id_info["eye"]}')
print(f'Height: {id_info["height"]}\n')
else:
print('Invalid ID')

Python search loop slow

I am running a search on a list of ads (adscrape). Each ad is a dict within adscrape (e.g. ad below). It searches through a list of IDs (database_ids) which could be between 200,000 - 1,000,000 items long. I want to find any ads in adscrape that don't have an ID already in database_ids.
My current code is below. It takes a loooong time, and multiple seconds for each ad to scan through database_ids. Is there a more efficient/faster way of running this (finding which items in a big list, are in another big list)?
database_ids = ['id1','id2','id3'...]
ad = {'body': u'\xa0SUV', 'loc': u'SA', 'last scan': '06/02/16', 'eng': u'\xa06cyl 2.7L ', 'make': u'Hyundai', 'year': u'2006', 'id': u'OAG-AD-12371713', 'first scan': '06/02/16', 'odo': u'168911', 'active': 'Y', 'adtype': u'Dealer: Used Car', 'model': u'Tucson Auto 4x4 ', 'trans': u'\xa0Automatic', 'price': u'9990'}
for ad in adscrape:
ad['last scan'] = date
ad['active'] = 'Y'
adscrape_ids.append(ad['id'])
if ad['id'] not in database_ids:
ad['first scan'] = date
print 'new ad:',ad
newads.append(ad)
`You can use list comprehensions for this as the code base given below. Use the existing database_ids list and adscrape dict as given above.
Code base:
new_adds_ids = [ad for ad in adscrape if ad['id'] not in database_ids]`
You can build ids_map as dict and check whether id in list by accessing key in that ids_map as in code snippet below:
database_ids = ['id1','id2','id3']
ad = {'id': u'OAG-AD-12371713', 'body': u'\xa0SUV', 'loc': u'SA', 'last scan': '06/02/16', 'eng': u'\xa06cyl 2.7L ', 'make': u'Hyundai', 'year': u'2006', 'first scan': '06/02/16', 'odo': u'168911', 'active': 'Y', 'adtype': u'Dealer: Used Car', 'model': u'Tucson Auto 4x4 ', 'trans': u'\xa0Automatic', 'price': u'9990'}
#build ids map
ids_map = dict((k, v) for v, k in enumerate(database_ids))
for ad in adscrape:
# some logic before checking whether id in database_ids
try:
ids_map[ad['id']]
except KeyError:
pass
else:
#error not thrown perform logic for existed ids
print 'id %s in list' % ad['id']

issue in list of dict

class MyOwnClass:
# list who contains the queries
queries = []
# a template dict
template_query = {}
template_query['name'] = 'mat'
template_query['age'] = '12'
obj = MyOwnClass()
query = obj.template_query
query['name'] = 'sam'
query['age'] = '23'
obj.queries.append(query)
query2 = obj.template_query
query2['name'] = 'dj'
query2['age'] = '19'
obj.queries.append(query2)
print obj.queries
It gives me
[{'age': '19', 'name': 'dj'}, {'age': '19', 'name': 'dj'}]
while I expect to have
[{'age': '23' , 'name': 'sam'}, {'age': '19', 'name': 'dj'}]
I thought to use a template for this list because I'm gonna to use it very often and there are some default variable who does not need to be changed.
Why does doing it the template_query itself changes? I'm new to python and I'm getting pretty confused.
this is because you are pointing to the same dictionary each time ... and overwriting the keys ...
# query = obj.template_query - dont need this
query = {}
query['name'] = 'sam'
query['age'] = '23'
obj.queries.append(query)
query2 = {} #obj.template_query-dont need this
query2['name'] = 'dj'
query2['age'] = '19'
obj.queries.append(query2)
this should demonstrate your problem
>>> q = {'a':1}
>>> lst = []
>>> lst.append(q)
>>> q['a']=2
>>> lst
[{'a': 2}]
>>> lst.append(q)
>>> lst
[{'a': 2}, {'a': 2}]
you could implement your class differently
class MyOwnClass:
# a template dict
#property
def template_query():
return {'name':'default','age':-1}
this will make obj.template_query return a new dict each time
This is because query and query2 are both referring to the same object. obj.template_query, in this case.
Better to make a template factory:
def template_query(**kwargs):
template = {'name': 'some default value',
'age': 'another default value',
'car': 'generic car name'}
template.update(**kwargs)
return template
That creates a new dictionary every time it's called. So you can do:
>>> my_query = template_query(name="sam")
>>> my_query
{'name': 'sam', 'age': 'another default value', 'car': 'generic car name'}
You're copying the same dict into query2. Instead, you might want to create the needed dict by creating a function template_query() and constructing a new dict each time:
class MyOwnClass:
# a template dict
def template_query():
d = {}
d['name'] = 'mat'
d['age'] = '12'
d['car'] = 'ferrari'
return d

Categories