import operator
pay = {}
lowestPay={}
averagePay={}
pay["Developers"]=[35,22,18,36]
pay["Designers"]=[25,65,24,45]
pay["Testers"]=[34,52,12,32]
userInput=int(input("How would you like the menu to be sorted?\n1 for Dictionary keys sorted in alphabetical order\n2 for Sort each list of employee’s pay rates from highest to lowest\n3 for Lowest pay level in each list sorted from highest to lowest\n4 for Average pay per department sorted from highest to lowest"))
if userInput == 1:
for key,value in pay.items():
sortedDictionary = sorted(pay)
print (sortedDictionary)
if userInput == 2:
for key,value in pay.items():
value.sort()
value.reverse()
print(key,value)
if userInput == 3:
for key,value in pay.items():
value.sort()
lowestPay [key]=value.pop()
lowestPaySorted = sorted(pay.items(),key=operator.itemgetter(1),reverse=True)
print (lowestPay)
if userInput == 4:
for key,value in pay.items():
average = sum(value)/len(value)
averagePay [key]=(average)
averagePaySorted = sorted(averagePay.items(),key=operator.itemgetter(1),reverse=True)
for keys in averagePaySorted:
print (keys)
for value in averagePaySorted[keys]:
print (value,':',cars[keys][value])
Above I have my program for sorting lists. I need to print the dictionary averagePaySorted. I am quite new to this so I am not to sure what to do as you can see I tried to attempt printing this from some other pages but I got this error:
... line 33, in <module>
for value in averagePaySorted[keys]:
TypeError: list indices must be integers, not tuple
I have no idea what that means I need it to out look something like this
B
color : 3
speed : 60
A
color : 2
speed : 70
but this was taken from a different forum to save time
To print a dictionary, check out pprint. E.g.,
print pformat(averagePaySorted)
Or, a more complete example:
from pprint import pformat
mydict = {'a': 1, 'b': 2, c: [4, 5, 6]}
print pformat(mydict)
pprint handles nesting, and
advanced options are available.
E.g.,
print pformat(mydict, width=1)
produces:
{'a': 1,
'b': 2,
'c': [4,
5,
6]}
The problem you have is because keys on this scenario is a tuple (key, value)
To print this, use something similar to
for key,value in list:
print key, ':', value
Related
I'd like to write a function that will take one argument (a text file) to use its contents as keys and assign values to the keys. But I'd like the keys to go from 1 to n:
{'A': 1, 'B': 2, 'C': 3, 'D': 4... }.
I tried to write something like this:
Base code which kind of works:
filename = 'words.txt'
with open(filename, 'r') as f:
text = f.read()
ready_text = text.split()
def create_dict(lst):
""" go through the arg, stores items in it as keys in a dict"""
dictionary = dict()
for item in lst:
if item not in dictionary:
dictionary[item] = 1
else:
dictionary[item] += 1
return dictionary
print(create_dict(ready_text))
The output: {'A': 1, 'B': 1, 'C': 1, 'D': 1... }.
Attempt to make the thing work:
def create_dict(lst):
""" go through the arg, stores items in it as keys in a dict"""
dictionary = dict()
values = list(range(100)) # values
for item in lst:
if item not in dictionary:
for value in values:
dictionary[item] = values[value]
else:
dictionary[item] = values[value]
return dictionary
The output: {'A': 99, 'B': 99, 'C': 99, 'D': 99... }.
My attempt doesn't work. It gives all the keys 99 as their value.
Bonus question: How can I optimaze my code and make it look more elegant/cleaner?
Thank you in advance.
You can use dict comprehension with enumerate (note the start parameter):
words.txt:
colorless green ideas sleep furiously
Code:
with open('words.txt', 'r') as f:
words = f.read().split()
dct = {word: i for i, word in enumerate(words, start=1)}
print(dct)
# {'colorless': 1, 'green': 2, 'ideas': 3, 'sleep': 4, 'furiously': 5}
Note that "to be or not to be" will result in {'to': 5, 'be': 6, 'or': 3, 'not': 4}, perhaps what you don't want. Having only one entry out of two (same) words is not the result of the algorithm here. Rather, it is inevitable as long as you use a dict.
Your program sends a list of strings to create_dict. For each string in the list, if that string is not in the dictionary, then the dictionary value for that key is set to 1. If that string has been encountered before, then the value of that key is increased by 1. So, since every key is being set to 1, then that must mean there are no repeat keys anywhere, meaning you're sending a list of unique strings.
So, in order to have the numerical values increase with each new key, you just have to increment some number during your loop:
num = 0
for item in lst:
num += 1
dictionary[item] = num
There's an easier way to loop through both numbers and list items at the same time, via enumerate():
for num, item in enumerate(lst, start=1): # start at 1 and not 0
dictionary[item] = num
You can use this code. If an item has been in the lst more than once, the idx is considered one time in dictionary!
def create_dict(lst):
""" go through the arg, stores items in it as keys in a dict"""
dictionary = dict()
idx = 1
for item in lst:
if item not in dictionary:
dictionary[item]=idx
idx += 1
return dictionary
I feel like i'm loosing my mind over this...
So I have added comments twice because i think i'm not really making sense. The code I have is more psuedocode because I have been going in circles.
The idea is to have a list of items that have a dictionary containing various prices, with various quantity's according to that price. Ideally I want to insert them in order of the name, then in order of the price
Here is what I have so far.
MyList = []
print(MyList)
def insertIntoList(listToAdd):
"""insert into MyList if name not in first element of each list
if the name is in the list, check to see if the first element of
any dictionary has the same value, if it does, add the last element
to the last element of that dictionary element"""
if len(MyList) == 0:
MyList.append(listToAdd)
for ind, i in enumerate(listToAdd):
#for each list in listToAdd
if i in MyList:
#if name in MyList
for item in listToAdd[1][0]:
if item in MyList[ind] == listToAdd[1][0]:
#if the first element of each dictionary
# in the list is equivalent to the first element
# of the dict, then increment the last element
MyList += listToAdd[1][1]
else:
#otherwise add the new dictionary to the list
MyList.append(listToAdd[1])
else:
#otherwise if name isnt in MyList
MyList.append(listToAdd)
insertIntoList(["Foo", [{1010:10101010}]])
insertIntoList(["Bar", [{0:1}]])
insertIntoList(["Bar", [{1:1}]])
insertIntoList(["Foo", [{1010:5}]])
print(MyList)
This should print;
[["Bar", [{0:1}, {1:1}]], ["Foo", [{1010:10101015}]]]
Perhaps you should use a better data structure like,
$ cat price.py
from collections import defaultdict
d = defaultdict(dict)
def insert(key, value):
for k,v in value.items():
d[key].setdefault(k, 0)
d[key][k] += v
insert("Foo", {1010:10101010})
insert("Bar", {0:1})
insert("Bar", {1:1})
insert("Foo", {1010:5})
print(dict(d))
print([[key, [{k:v} for k,v in value.items()]] for key,value in d.items()])
Since, the data to be inserted is based on the key, a dict should be apt here.
And you could shape it to be however you want in the end like,
Output:
$ python price.py
'Foo': {1010: 10101015}, 'Bar': {0: 1, 1: 1}}
[['Foo', [{1010: 10101015}]], ['Bar', [{0: 1}, {1: 1}]]]
You could do something like this
def insert(result, key, price, quantity):
priceDict = result.get(key, {price: 0})
priceDict[price] += quantity
result[key] = priceDict
return result
result = {}
print(result) # {}
insert(result, "Foo", 1010, 10101010)
insert(result, "Bar", 0, 1)
insert(result, "Foo", 1010, 5)
print(result) # {'Foo': {1010: 10101015}, 'Bar': {0: 1}}
I have a dictionary with the following structure:
results =
{1: {'A': 10,
'B' : 11,
'C': 12},
5: {'A': 20,
'B' : 21,
'C': 22}}
I have tried to iterate through this dictionary using this for loop:
total_A = []
for key in results:
total_A.append(results[key]["A"])
print total_A
But it is not working, because it is inputting key as 1 and 2 each time it loops. How am i able to iterate through the results dictionary using index as 1 and 5? (they are of type integer)
Try this. It will loop through your dictionary keys.
for key in results.keys():
Like this:
total_A = []
for key in results.keys():
total_A.append(results[key]["A"])
print total_A
Result is
[10, 20]
In your case you could do
for key, value in results.items():
total_A.append(value["A"])
Then value will contain the value of the dictionary element, and you don't have to do the results[key] lookup explicitly.
I am writing a function that take dictionary input and return list of keys which have unique values in that dictionary. Consider,
ip = {1: 1, 2: 1, 3: 3}
so output should be [3] as key 3 has unique value which is not present in dict.
Now there is problem in given fuction:
def uniqueValues(aDict):
dicta = aDict
dum = 0
for key in aDict.keys():
for key1 in aDict.keys():
if key == key1:
dum = 0
else:
if aDict[key] == aDict[key1]:
if key in dicta:
dicta.pop(key)
if key1 in dicta:
dicta.pop(key1)
listop = dicta.keys()
print listop
return listop
I am getting error like:
File "main.py", line 14, in uniqueValues
if aDict[key] == aDict[key1]: KeyError: 1
Where i am doing wrong?
Your main problem is this line:
dicta = aDict
You think you're making a copy of the dictionary, but actually you still have just one dictionary, so operations on dicta also change aDict (and so, you remove values from adict, they also get removed from aDict, and so you get your KeyError).
One solution would be
dicta = aDict.copy()
(You should also give your variables clearer names to make it more obvious to yourself what you're doing)
(edit) Also, an easier way of doing what you're doing:
def iter_unique_keys(d):
values = list(d.values())
for key, value in d.iteritems():
if values.count(value) == 1:
yield key
print list(iter_unique_keys({1: 1, 2: 1, 3: 3}))
Use Counter from collections library:
from collections import Counter
ip = {
1: 1,
2: 1,
3: 3,
4: 5,
5: 1,
6: 1,
7: 9
}
# Generate a dict with the amount of occurrences of each value in 'ip' dict
count = Counter([x for x in ip.values()])
# For each item (key,value) in ip dict, we check if the amount of occurrences of its value.
# We add it to the 'results' list only if the amount of occurrences equals to 1.
results = [x for x,y in ip.items() if count[y] == 1]
# Finally, print the results list
print results
Output:
[3, 4, 7]
I have a dictionary to which I want to append to each drug, a list of numbers. Like this:
append(0), append(1234), append(123), etc.
def make_drug_dictionary(data):
drug_dictionary={'MORPHINE':[],
'OXYCODONE':[],
'OXYMORPHONE':[],
'METHADONE':[],
'BUPRENORPHINE':[],
'HYDROMORPHONE':[],
'CODEINE':[],
'HYDROCODONE':[]}
prev = None
for row in data:
if prev is None or prev==row[11]:
drug_dictionary.append[row[11][]
return drug_dictionary
I later want to be able to access the entirr set of entries in, for example, 'MORPHINE'.
How do I append a number into the drug_dictionary?
How do I later traverse through each entry?
Just use append:
list1 = [1, 2, 3, 4, 5]
list2 = [123, 234, 456]
d = {'a': [], 'b': []}
d['a'].append(list1)
d['a'].append(list2)
print d['a']
You should use append to add to the list. But also here are few code tips:
I would use dict.setdefault or defaultdict to avoid having to specify the empty list in the dictionary definition.
If you use prev to to filter out duplicated values you can simplfy the code using groupby from itertools
Your code with the amendments looks as follows:
import itertools
def make_drug_dictionary(data):
drug_dictionary = {}
for key, row in itertools.groupby(data, lambda x: x[11]):
drug_dictionary.setdefault(key,[]).append(row[?])
return drug_dictionary
If you don't know how groupby works just check this example:
>>> list(key for key, val in itertools.groupby('aaabbccddeefaa'))
['a', 'b', 'c', 'd', 'e', 'f', 'a']
It sounds as if you are trying to setup a list of lists as each value in the dictionary. Your initial value for each drug in the dict is []. So assuming that you have list1 that you want to append to the list for 'MORPHINE' you should do:
drug_dictionary['MORPHINE'].append(list1)
You can then access the various lists in the way that you want as drug_dictionary['MORPHINE'][0] etc.
To traverse the lists stored against key you would do:
for listx in drug_dictionary['MORPHINE'] :
do stuff on listx
To append entries to the table:
for row in data:
name = ??? # figure out the name of the drug
number = ??? # figure out the number you want to append
drug_dictionary[name].append(number)
To loop through the data:
for name, numbers in drug_dictionary.items():
print name, numbers
If you want to append to the lists of each key inside a dictionary, you can append new values to them using + operator (tested in Python 3.7):
mydict = {'a':[], 'b':[]}
print(mydict)
mydict['a'] += [1,3]
mydict['b'] += [4,6]
print(mydict)
mydict['a'] += [2,8]
print(mydict)
and the output:
{'a': [], 'b': []}
{'a': [1, 3], 'b': [4, 6]}
{'a': [1, 3, 2, 8], 'b': [4, 6]}
mydict['a'].extend([1,3]) will do the job same as + without creating a new list (efficient way).
You can use the update() method as well
d = {"a": 2}
d.update{"b": 4}
print(d) # {"a": 2, "b": 4}
how do i append a number into the drug_dictionary?
Do you wish to add "a number" or a set of values?
I use dictionaries to build associative arrays and lookup tables quite a bit.
Since python is so good at handling strings,
I often use a string and add the values into a dict as a comma separated string
drug_dictionary = {}
drug_dictionary={'MORPHINE':'',
'OXYCODONE':'',
'OXYMORPHONE':'',
'METHADONE':'',
'BUPRENORPHINE':'',
'HYDROMORPHONE':'',
'CODEINE':'',
'HYDROCODONE':''}
drug_to_update = 'MORPHINE'
try:
oldvalue = drug_dictionary[drug_to_update]
except:
oldvalue = ''
# to increment a value
try:
newval = int(oldval)
newval += 1
except:
newval = 1
drug_dictionary[drug_to_update] = "%s" % newval
# to append a value
try:
newval = int(oldval)
newval += 1
except:
newval = 1
drug_dictionary[drug_to_update] = "%s,%s" % (oldval,newval)
The Append method allows for storing a list of values but leaves you will a trailing comma
which you can remove with
drug_dictionary[drug_to_update][:-1]
the result of the appending the values as a string means that you can append lists of values as you need too and
print "'%s':'%s'" % ( drug_to_update, drug_dictionary[drug_to_update])
can return
'MORPHINE':'10,5,7,42,12,'
vowels = ("a","e","i","o","u") #create a list of vowels
my_str = ("this is my dog and a cat") # sample string to get the vowel count
count = {}.fromkeys(vowels,0) #create dict initializing the count to each vowel to 0
for char in my_str :
if char in count:
count[char] += 1
print(count)