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)
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
Does anyone know how to convert below for loop into a list or dictionary comprehension in one line? type(letter) = string,type(stringOne) = string,type(dictResult) = dictionary.For example, stringOne = 'abcddd', I want the output to be dictResult = {'a': 1, 'b': 1, 'c': 1, 'd': 3} Thanks!!!
stringOne = 'abcddd'
dictResult = {}
for letter in stringOne:
dictResult[letter] = dictResult.get(letter,0) + 1
Find unique keys with set and then count. Note the set doesn't not keep (keys) insertion order!
stringOne = 'abcddd'
dictResult = {char: stringOne.count(char) for char in set(stringOne)}
print(dictResult)
Make use of Counter will do. Save you the time to do a loop for the string. Can just convert to dictionary later if you required it to be in dictionary type.
from collections import Counter
counter = Counter(stringOne)
dict(counter)
How can I create a key:value pair in a first loop and then just append values in subsequent loops?
For example:
a = [1,2,3]
b = [8,9,10]
c = [4,6,5]
myList= [a,b,c]
positions= ['first_position', 'second_position', 'third_position']
I would like to create a dictionary which records the position values for each letter so:
mydict = {'first_position':[1,8,4], 'second_position':[2,9,6], 'third_position':[3,10,5]}
Imagine that instead of 3 letters with 3 values each, I had millions. How could I loop through each letter and:
In the first loop create the key:value pair 'first_position':[1]
In subsequent loops append values to the corresponding key: 'first_position':[1,8,4]
Thanks!
Try this code:
mydict = {}
for i in range(len(positions)):
mydict[positions[i]] = [each[i] for each in myList]
Output:
{'first_position': [1, 8, 4],
'second_position': [2, 9, 6],
'third_position': [3, 10, 5]}
dictionary.get('key') will return None if the key doesn't exist. So, you can check if the value is None and then append it if it isn't.
dict = {}
for list in myList:
for position, val in enumerate(list):
this_position = positions[position]
if dict.get(this_position) is not None:
dict[this_position].append(val)
else:
dict[this_position] = [val]
The zip function will iterate the i'th values of positions, a, b and c in order. So,
a = [1,2,3]
b = [8,9,10]
c = [4,6,5]
positions= ['first_position', 'second_position', 'third_position']
sources = [positions, a, b, c]
mydict = {vals[0]:vals[1:] for vals in zip(*sources)}
print(mydict)
This created tuples which is usually fine if the lists are read only. Otherwise do
mydict = {vals[0]:list(vals[1:]) for vals in zip(*sources)}
I have two dictionaries, RFQDict and AwardsDict. I want to take the keys of RFQdict and search through AwardsDict values for matches.
So I tried this
RFQDict = {}
AwardsDict = {}
# Fetch RFQ
RFQref = db.reference('TestRFQ')
snapshot = RFQref.get()
for key, val in snapshot.items():
RFQDict[key] = val
print('{0} => {1}'.format(key, val))
Awardsref = db.reference('DibbsAwards')
dsnapshot = Awardsref.get()
for key, val in dsnapshot.items():
AwardsDict[key] = val
print('{0} => {1}'.format(key, val))
for key in RFQDict:
if key in AwardsDict.values():
print(key+ " Match found")
is this the way to do it or there is a better way and how could return the key and values where the match was found?
In python3 you can do AwardsDict.values() & RFQDict.keys() and you will get a set with the common key/values.
The '&' operator is used for set intersection and works with the dictionary views returned by values() and keys(). More information of the view returned by those methods: https://docs.python.org/3/library/stdtypes.html?highlight=dictview#dictionary-view-objects
If you want to store the keys and values that match, it would probably be best to store the key and value from the second dictionary since if you just store the matching key and value you will have elements like (a, a) which won't really tell you much about where they matched in the second dictionary. Maybe something like this
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'x': 'a', 'y': 1, 'z': 'c'}
res = [(i, {j: d2[j]}) for i in d1 for j in d2 if i == d2[j]]
print(res)
# [('a': {'x': 'a'}), ('c': {'z': 'c'})]
I would do a list comprehension:
result=[x for x in AwardsDict.values() if x in RFQDict.keys() ]
This way you get a list keeping the duplicates. That is, if a RFQ key is presented in more than one value in AwardsDict. With the & operator you loss that information (as sets only have unique elements).
For example:
RFQDict = {}
AwardsDict = {}
for i in range(5):
RFQDict[i]=0
for i in range(5):
AwardsDict[i]=i
for i in range(5,11):
AwardsDict[i]=i//2 #integer division, i=8 and i=9 get a value of 4
result=[x for x in AwardsDict.values() if x in RFQDict.keys() ]
print('{}'.format(result))
#output [0, 1, 2, 3, 4, 2, 3, 3, 4, 4]
I am trying to build a dict from a set of unique values to serve as the keys and a zipped list of tuples to provide the items.
set = ("a","b","c")
lst 1 =("a","a","b","b","c","d","d")
lst 2 =(1,2,3,3,4,5,6,)
zip = [("a",1),("a",2),("b",3),("b",3),("c",4),("d",5)("d",6)
dct = {"a":1,2 "b":3,3 "c":4 "d":5,6}
But I am getting:
dct = {"a":1,"b":3,"c":4,"d":5}
here is my code so far:
#make two lists
rtList = ["EVT","EVT","EVT","EVT","EVT","EVT","EVT","HIL"]
raList = ["C64G","C64R","C64O","C32G","C96G","C96R","C96O","RA96O"]
# make a set of unique codes in the first list
routes = set()
for r in rtList:
routes.add(r)
#zip the lists
RtRaList = zip(rtList,raList)
#print RtRaList
# make a dictionary with list one as the keys and list two as the values
SrvCodeDct = {}
for key, item in RtRaList:
for r in routes:
if r == key:
SrvCodeDct[r] = item
for key, item in SrvCodeDct.items():
print key, item
You don't need any of that. Just use a collections.defaultdict.
import collections
rtList = ["EVT","EVT","EVT","EVT","EVT","EVT","EVT","HIL"]
raList = ["C64G","C64R","C64O","C32G","C96G","C96R","C96O","RA96O"]
d = collections.defaultdict(list)
for k,v in zip(rtList, raList):
d[k].append(v)
You may achieve this using dict.setdefault method as:
my_dict = {}
for i, j in zip(l1, l2):
my_dict.setdefault(i, []).append(j)
which will return value of my_dict as:
>>> my_dict
{'a': [1, 2], 'c': [4], 'b': [3, 3], 'd': [5, 6]}
OR, use collections.defaultdict as mentioned by TigerhawkT3.
Issue with your code: You are not making the check for existing key. Everytime you do SrvCodeDct[r] = item, you are updating the previous value of r key with item value. In order to fix this, you have to add if condition as:
l1 = ("a","a","b","b","c","d","d")
l2 = (1,2,3,3,4,5,6,)
my_dict = {}
for i, j in zip(l1, l2):
if i in my_dict: # your `if` check
my_dict[i].append(j) # append value to existing list
else:
my_dict[i] = [j]
>>> my_dict
{'a': [1, 2], 'c': [4], 'b': [3, 3], 'd': [5, 6]}
However this code can be simplified using collections.defaultdict (as mentioned by TigerhawkT3), OR using dict.setdefault method as:
my_dict = {}
for i, j in zip(l1, l2):
my_dict.setdefault(i, []).append(j)
In dicts, all keys are unique, and each key can only have one value.
The easiest way to solve this is have the value of the dictionary be a list, as to emulate what is called a multimap. In the list, you have all the elements that is mapped-to by the key.
EDIT:
You might want to check out this PyPI package: https://pypi.python.org/pypi/multidict
Under the hood, however, it probably works as described above.
Afaik, there is nothing built-in that supports what you are after.