Updating list of dictionaries in python using map - python

So I have a list that looks like this:
users = [{'id': 11, 'name': 'First'}, {'id': 22, 'name': 'Second'}, {'id':33, 'name': 'Third'}]
What I want to do is to update a users name by passing id, creating new user, and replacing old one with new user.
I want to get list of updated users, like this:
updated_users = list(map(update, users))
If I could send id to update func as argument, what I want to do, would look something like this:
def update(id):
if user['id'] == id:
new_user = some_fun()
user = new_user
return user
How should my update function look like?

I don't know why you want to use map and I think it's a wrong approach because map isn't for this kind of things (you could make it work for sure but it wouldn't be the way to go)
You can do something like that:
users = [{'id': 11, 'name': 'First'}, {'id': 22, 'name': 'Second'}, {'id':33, 'name': 'Third'}]
def update(id, new_name):
for user in users:
if user["id"] == id:
user["name"] = new_name
return
users.append({'id':id,'name':new_name}) # if not exist add user
print(users)
update(11,"Last")
update(1, "New_First")
print(users)
Output:
[{'id': 11, 'name': 'First'}, {'id': 22, 'name': 'Second'}, {'id': 33, 'name': 'Third'}]
[{'id': 11, 'name': 'Last'}, {'id': 22, 'name': 'Second'}, {'id': 33, 'name': 'Third'}, {'id': 1, 'name': 'New_First'}]

Related

Find element in a list of dicts based on value

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

appending API request to another dictionary

making an application where I need to get field 'workers' from an API request and pass those to another dict.. dictionary is behaving strangely and I cannot seem to append through += or .update like a normal list or tupple.
main.py
# worker_detail - contains a list of filtered workers
# workers - contains a list of all workers
information = {}
reported_workers = []
for person in workers:
if person['id'] in worker_detail:
reported_workers += person
print(reported_workers)
If I use the above logic it will only print the fields in a dictionary without and workers..
['id', 'first_name', 'last_name', 'email', 'phone_number', 'hire_date', 'job_id', 'salary', 'commission_pct', 'manager_id', 'department_id', 'id', 'first_name', 'last_name', 'email', 'phone_number', 'hire_date', 'job_id', 'salary', 'commission_pct', 'manager_id', 'department_id']
If I print(person) output will be a dictionary containing all the neccessary fields and it's details
{'id': 1, 'first_name': 'Steven', 'last_name': 'King', 'email': 'SKING', 'phone_number': 5151234567, 'hire_date': '2021-06-17', 'job_id': 'AD_PRES', 'salary': 24000, 'commission_pct': 0, 'manager_id': 0, 'department_id': 0}
{'id': 2, 'first_name': 'Neena', 'last_name': 'Kochhar', 'email': 'NKOCHHAR', 'phone_number': 5151234568, 'hire_date': '2020-06-17', 'job_id': 'AD_VP', 'salary': 17000, 'commission_pct': 0, 'manager_id': 100, 'department_id': 90}
{'id': 5, 'first_name': 'Bruce', 'last_name': 'Ernst', 'email': 'BERNST', 'phone_number': 5151234571, 'hire_date': '2016-07-17', 'job_id': 'IT_PROG', 'salary': 6000, 'commission_pct': 0, 'manager_id': 103, 'department_id': 60}
{'id': 9, 'first_name': 'Inbal', 'last_name': 'Amor', 'email': 'IMOR', 'phone_number': 5151234575, 'hire_date': '2013-08-23', 'job_id': 'IT_PROG', 'salary': 5000, 'commission_pct': 0, 'manager_id': 104, 'department_id': 60}
Try using a list comprehension:
reported_workers = [person for person in workers if person in worker_detail]
If you find yourself looping over a list to make a new list, often you can replace it with this really nifty structure. It will let you abstract away your criteria also. If you want your worker_detail to be a more specific tuning, you can create a function for it and just call that in the list comprehension
def is_worker(person_id):
for worker in worker_detail:
if worker['id'] == person_id: return True
return False
reported_workers = [person for person in workers if is_worker(person['id'])]
append, dont +=
information = {}
reported_workers = []
for person in workers:
if person in worker_detail:
reported_workers.append(person)
print(reported_workers)

how to sort list of dict by dict[key][key] in one line(Python3)

I want to sort by uid
rsp=[
{'user': {'uid': 1, 'name': 'Bob'}},
{'user': {'uid': 5, 'name': 'Sid'}},
{'user': {'uid': 2, 'name': 'Cas'}},
]
to
rsp=[
{'user': {'uid': 1, 'name': 'Bob'}},
{'user': {'uid': 2, 'name': 'Cas'}},
{'user': {'uid': 5, 'name': 'Sid'}},
]
Ive tried this way.....but it doesn't work
result = sorted(rsp, key=itemgetter('user').itemgetter('uid'))
You can pass a lambda function to the key argument:
result = sorted(rsp, key=lambda x: x.get('user', {}).get('uid', -1) )
In this case I am using get to ensure the sort does not fail if one of the elements does not have a user key, and any sub-dictionaries that do not have a uid key will be place first.
You can try this as your key to sort your list of dictionaries:
rsp.sort(key = lambda x: x['user']['uid'])
>>> rsp
[{'user': {'uid': 1, 'name': 'Bob'}}, {'user': {'uid': 2, 'name': 'Cas'}}, {'user': {'uid': 5, 'name': 'Sid'}}]

What is the best way to save the model when the input is json?

I have below json as input from the client
[
{'id': 0, 'name': 'Housing', 'value': 3},
{'id': 1, 'name': 'Bank', 'value': 8},
{'id': 2, 'name': 'Entertainment', 'value': 3}
]
It is being assigned to inputV_wc object in my view like below
View:
def savemore(request):
if request.method == "POST":
data=json.loads(request.body.decode())
inputV_wc = data['wc']
else:
response_data = 'You have not saved any data!'
return HttpResponse(response_data, content_type="text/plain")
try:
if not inputV_wc:
test=''
else:
# WC - Insert wc again on each save rather update - time consuming
if js_wex.objects.filter(pid = request.session.get('pid')).exists():
js_wex.objects.filter(pid=request.session.get('pid')).delete()
wc = js_wex(pid=request.session.get('pid'), wcname=inputV_wc[0]['name'],rating=inputV_wc[0]['value'],ordernum=inputV_wc[0]['id'])
wc.save()
wc = js_wex(pid=request.session.get('pid'), wcname=inputV_wc[1]['name'],rating=inputV_wc[1]['value'],ordernum=inputV_wc[1]['id'])
wc.save()
wc = js_wex(pid=request.session.get('pid'), wcname=inputV_wc[2]['name'],rating=inputV_wc[2]['value'],ordernum=inputV_wc[2]['id'])
wc.save()
except Exception as e:
response_data = 'Ouch! Something went wrong!'+str(e)
return HttpResponse(response_data, content_type="text/plain")
Currently if my input json has 5 rows, certainly the above view fails with Index out of range..
and if input json has 2 rows it again fails with missing entry - model cannot be saved.
How can I write my view such that if json has varied number of objects like
input from one user -
[
{'id': 0, 'name': 'Housing', 'value': 14},
{'id': 1, 'name': 'Bank', 'value': 18}
]
input from other user -
[
{'id': 0, 'name': 'Housing', 'value': 3},
{'id': 1, 'name': 'Bank', 'value': 18},
{'id': 2, 'name': 'Housing1', 'value': 14},
{'id': 3, 'name': 'Bank1', 'value': 12}
]
can be handled ?
Json rows could be from 1 to 15 maximum for each input.
I read about using **kwargs, for handling similar scenario.. but I couldn't figure out how to apply for saving my model for varied json input.
If I understand you correctly, I think you just want to use a for statement:
for row in inputV_wc:
wc = js_wex(pid=request.session.get('pid'), wcname=row['name'], rating=row['value'], ordernum=row['id'])
wc.save()
If you want to insert all the objects at once, based on what you have shown you could probably use bulk_create:
rows = []
for row in inputV_wc:
wc = js_wex(pid=request.session.get('pid'), wcname=row['name'], rating=row['value'], ordernum=row['id'])
rows.append(wc)
js_wex.objects.bulk_create(rows)

Loop in dict python

I have already looked around but have not found any help for this.
This is my dict:
{'id': 1, 'name': 'Studio Pierrot'}
{'id': 29, 'name': 'VAP'}
{'id': 102, 'name': 'FUNimation Entertainment'}
{'id': 148, 'name': 'Hakusensha'}
{'id': 238, 'name': 'AT-X'}
{'id': 751, 'name': 'Marvelous AQL'}
{'id': 1211, 'name': 'Tokyo MX'}
aproducers = an.info['Producers'][0]['name']
for key in aproducers:
print key
The output is like:
S
t
u
d
i
o
...
I want to output just Studio Pierrot,VAP,FUNimation Entertainment...
You’re looping over a string, the single name value of the first producer. You need to loop over the producers instead:
for producer in an.info['Producers']:
print producer['name']
I suggest you to use the methods keys() values() items() and to use nested dicts
for the last question you can just use:
listproducer = []
for producer in an.info['Producers']:
listproducer.append( producer['name'] )

Categories