python dictionary - list of lists to dict - python

I'm trying to take list of lists and convert in to dictionary. See code below
yearend = [['empl','rating1','rating2','rating3'],['mike','4','4','5'],
['sam','3','2','5'],['doug','5','5','5']]
extract the employee names
employee = [item[0] for item in yearend] #select 1st item from each list
employee.pop(0) # pop out the empl
print(employee)
### output##################################################
##['mike', 'sam', 'doug']###################################
###Output###################################################
###extract the various rating types
yearend1 = yearend [:] # make a copy
rating = yearend1.pop(0) # Pop out the 1st list
rating.pop(0)
print(rating)
### output##################################################
##['rating1', 'rating2', 'rating3']#########################
###Output###################################################
# pick employee and rating and convert rating to numeric
empl_rating = {t[0]:t[1:] for t in yearend1}
for key,value in empl_rating.items():
value = list(map(int, value))
empl_rating[key] = value
print(empl_rating)
### output##################################################
##{'mike': [4, 4, 5], 'sam': [3, 2, 5], 'doug': [5, 5, 5]}##
###Output###################################################
I extracted the data like above and now Iam trying to put together in to dict (New_dicts) so that when
New_dicts['sam']['rating1']
I get 3 or
New_dicts['doug']['rating3']
I get 5. What I'm struggling is how to put this data together?

def todict(ratings) :
a ={}
a["rating1"] = ratings [0]
a["rating2"] = ratings [1]
a["rating3"] = ratings [2]
return a
One way to solve your problem is to get rid of the first row with the headings then just do:
{item[0] : todict(item[1:])
for item in your_list}
BTW this sol is based of off how you wanted to index it. I'm sure there is a more generic sol out there.
Because what you want is essentially just a nested dict

You can use a dict comprehension:
New_dicts = {line[0]: {yearend[0][i + 1]: int(rating) for i, rating in enumerate(line[1:])} for line in yearend[1:]}

Related

Find max value of a column based on another in python

i have 2d list implementation as follows. It shows no. of times every student topped in exams:-
list = main_record
['student1',1]
['student2',1]
['student2',2]
['student1',5]
['student3',3]
i have another list of unique students as follows:-
list = students_enrolled
['student1','student2','student3']
which i want to display student ranking based on their distinctions as follows:-
list = student_ranking
['student1','student3','student2']
What built in functions can be useful. I could not pose proper query on net. In other words i need python equivalent of following queries:-
select max(main_record[1]) where name = student1 >>> result = 5
select max(main_record[1]) where name = student2 >>> result = 2
select max(main_record[1]) where name = student3 >>> result = 3
You define a dict base key of studentX and save the max value for each student key then sort the students_enrolled base max value of each key.
from collections import defaultdict
main_record = [['student1',1], ['student2',1], ['student2',2], ['student1',5], ['student3',3]]
students_enrolled = ['student1','student2','student3']
# defind dict with negative infinity and update with max in each iteration
tmp_dct = defaultdict(lambda: float('-inf'))
for lst in main_record:
k, v = lst
tmp_dct[k] = max(tmp_dct[k], v)
print(tmp_dct)
students_enrolled.sort(key = lambda x: tmp_dct[x], reverse=True)
print(students_enrolled)
Output:
# tmp_dct =>
defaultdict(<function <lambda> at 0x7fd81044b1f0>,
{'student1': 5, 'student2': 2, 'student3': 3})
# students_enrolled after sorting
['student1', 'student3', 'student2']
If it is a 2D list it should look like this: l = [["student1", 2], ["student2", 3], ["student3", 4]]. To get the highest numeric value from the 2nd column you can use a loop like this:
numbers = []
for student in list:
numbers.append(student[1])
for num in numbers:
n = numbers.copy()
n.sort()
n.reverse()
student_index = numbers.index(n[0])
print(list[student_index], n[0])
numbers.remove(n[0])

Building dictionary of unique IDs for pairs of matching strings

I have a dataframe like this
#Test dataframe
import pandas as pd
import numpy as np
#Build df
titles = {'Title': ['title1', 'cat', 'dog']}
references = {'References': [['donkey','chicken'],['title1','dog'],['bird','snake']]}
df = pd.DataFrame({'Title': ['title1', 'cat', 'dog'], 'References': [['donkey','chicken'],['title1','dog'],['bird','snake']]})
#Insert IDs for UNIQUE titles
title_ids = {'IDs':list(np.arange(0,len(df)) + 1)}
df['IDs'] = list(np.arange(0,len(df)) + 1)
df = df[['Title','IDs','References']]
and I want to generate IDs for the references column that looks like the data frame below. If there is a matching between the strings, assign the same ID as in the IDs column and if not, assign a new unique ID.
My first attempt is using the function
#Matching function
def string_match(string1,string2):
if string1 == string2:
a = 1
else:
a = 0
return a
and to loop over each string/title combination but this gets tricky with multiple for loops and if statements. Is there a better way I can do this that is more pythonic?
# Explode to one reference per row
references = df["References"].explode()
# Combine existing titles with new title from References
titles = pd.concat([df["Title"], references]).unique()
# Assign each title an index number
mappings = {t: i + 1 for i, t in enumerate(titles)}
# Map the reference to the index number and convert to list
df["RefIDs"] = references.map(mappings).groupby(level=0).apply(list)
Let us try with factorize
s = df['References'].explode()
s[:] = pd.concat([df['Title'],s]).factorize()[0][len(df['Title']):]
df['new'] = (s+1).groupby(level=0).agg(list)
Out[237]:
0 [4, 5]
1 [1, 3]
2 [6, 7]
Name: References, dtype: object
In addition to the answers this can also be done with the help of a function, apply and lambda:
id_info=dict(df[['Title','IDs']].values)
def check(title,ref):
new_id_ = max(id_info.values()) #get latest id
ids=[]
for i in ref:
if i in id_info: #if Reference value is defined before, get its id
new_id=id_info[i]
else:
new_id=new_id_ + 1 #define a new id if not defined before and update dictionary to get latest id in next steps
new_id_+=1
id_info.update({i:new_id})
ids.append(new_id)
return ids
df['new_id']=df.apply(lambda x: check(x['Title'],x['References']),axis=1)
print(df)
'''
Title IDs References RefIDs
0 title1 1 ['donkey', 'chicken'] [4, 5]
1 cat 2 ['title1', 'dog'] [1, 3]
2 dog 3 ['bird', 'snake'] [6, 7]
'''

For a dict of list values, find the key with the maximum value for each index in the list

I have a dict with a few names as the keys, and each name has a value of a list with some numbers. I want to get the name (key) with the maximum value for each index of the list value.
I tried to write the following code but it doesn't work, I obtain the error AttributeError: 'str' object has no attribute 'keys' and I don't know why.
This is the code:
from Scheduler import Scheduler
class MaxSNR(Scheduler):
def allocuteUR(self, mapMobileMkn, tailleFrequence=1):
mapUniteResource = ["NonAllouer" for x in range(tailleFrequence)]
mknMax = max(mapMobileMkn, key=mapMobileMkn.get)
return mknMax
if __name__ == "__main__":
m = MaxSNR()
mapUniteResource = m.allocuteUR({'patrick': [40, 5], 'michel': [8, 3], 'edgard': [1, 10]}, tailleFrequence=2)
for key in mapUniteResource.keys:
nombre = MaxSNR(mapUniteResource)
print(nombre)
For the example above I expect the output to be:
patrick
edgard
Because 40 is the maximum value of the first index and 10 is the maximum value of the second index.
It will be more convenient to first separate the dict to names and values.
Now we want to zip the values in order to iterate over the index-matching items.
Now we need to find the index of the maximum value, so we can take its matching name.
d = {'patrick': [40, 5], 'michel': [8, 3], 'edgard': [1, 10]}
names, values = zip(*d.items())
for column in zip(*values):
index = max(range(len(column)), key=lambda i: column[i])
print(index, names[index])
Will give:
0 patrick
2 edgard

How to check a list for duplicates and add values if there are any?

I'm totally beginner with coding and just need help with some stuff.
My dream was to write a smart shopping list that automatically detects duplicates and increases the weight of duplicate products.
I get the shopping list from an external file which has the following form:
weight\n
ingredient\n
eg.
60
eggs
120
beef meat
25
pasta
120
eggs
etc...
After converting this files to dictionaries by this code:
final_list = []
def get_list(day_list):
for day in range(len(day_list)):
day += 1
day_to_open = f'Days/day{str(day)}.txt'
with open(day_to_open, 'r') as file:
day1 = file.readlines()
day1 = [item.rstrip() for item in day1]
x = 0
y = 1
list = []
for item in range(0, len(day1), 2):
dictio = {day1[y]: day1[x]}
x += 2
y += 2
list.append(dictio)
final_list.append(list)
list = []
for item in final_list:
list += item
return list
days = [1, 2, 3]
list = get_list(day_list=days)
Finally I get list of dictionaries like that:
[{'eggs': '60'}, {'beef meat': '120'}, {'pasta': '25'}, {'eggs': '120'}]
How can I iterate through the dictionary to check if any products are repeating, and if so leave one with the added weight?
For three weeks I have been trying to solve it, unfortunately to no avail.
Thank you very much for all your help!
#Edit
my goal is to make it look like this:
[{'eggs': 180}, {'beef meat': 120}, {'pasta': 25}]
#egg weight added (120 + 60)#
lis = [{'eggs': '60'}, {'beef meat': '120'}, {'pasta': '25'}, {'eggs': '120'}]
# make 1 dict from list of dicts and update max value
new = {}
for d in lis:
for k, v in d.items():
if (k not in new) or (int(v) > int(new[k])):
new[k] = v
# rebuild list of dicts
lis = [{k:v} for k, v in new.items()]
print(lis)
# [{'eggs': '120'}, {'beef meat': '120'}, {'pasta': '25'}]
As ShadowRanger has pointed out, it's not common practice to have a list of multiple dictionaries as you have done. Dictionaries are very useful if used correctly.
I'm not entirely sure the structure of the files you are reading, so I will just explain a way forward and leave it up to you to implement it. What I would suggest is that you first initiate a dictionary with all the necessary keys (ingredients in your case) with each of the values set to 0 (as an integer or float, rather than a string), so you would get a dictionary like this:
shopping_list = {'eggs': 0, 'beef meat': 0, 'pasta': 0}
Then, you will be able to access each of the values by calling the shopping_list dictionary and specifying the key of interest. For example, if you wanted to print the value of eggs, you would write:
print(shopping_list['eggs']) # this would return 0
You can then easily increase/decrease a value of interest; for example, to add 10 to pasta, you would write:
shopping_list['eggs'] += 10
Using this method, you can then iterate through each of your items, select the ingredient of interest and add the weight. So if you have duplicates, it will just add to the same ingredient. Again, I'm not sure the structure of the files you are reading, but it would be something along the lines of:
for ingredient, weight in file:
shopping_list[ingredient] += weight
Good luck for your dream - all the best!

How to compare two outputs of data in Python

I created 5 rooms with same Game id and print result (list if Rooms' id). i get Game with Id and print result (list of Rooms' id. I need to check if this two outputs (rooms id are matches).
for i in range(5):
post_req = requests.post(custom_url) # create 5 custom rooms with same Game id
json_data = post_req.text
python_data = json.loads(json_data)
for i in range(len(python_data["data"])):
first_list = python_data["data"][i]["id"]
print (first_list)
# Get Rooms with Game id. It should give a list of all rooms id created with same game id
custom_get_objects = requests.get(custom_url)
json_data = custom_get_objects.text
python_get_data = json.loads(json_data)
for i in range(len(python_get_data["data"])):
second_list = python_get_data["data"][i]["id"]
print (second_list)
How to program next following logic?
if first_list.data == second_list.data:
return True
my list.data output:
2b88a706-0ae0-4cac-84b3-8f69657ac8cd
402210ca-8397-4329-9c96-770f1d93ab43
78c9faae-74ad-44f8-9bab-b54bb8815afb
9a374566-d992-40a8-9e23-9cfe83ced532
f39794ed-d2f1-4443-a3f3-ef12534387d6
i tried to sort and iterated one list in another, but output is not what i expected. If you know or have any idea, please let me know.
If the order in your lists does not matter you can use sorted(listA) == sorted(listB) to compare them. If the order matters then simply use listA == listB.
Example:
aList = [2, 4, 5]
bList = [2, 5, 4]
print(aList == bList)
print(sorted(aList) == sorted(bList))
Output:
False
True

Categories