Outputing single strings in python - python

I'm in need of some assistance in this code problem from a MOOC on python programming that I'm taking. This is just for self-learning, and not for any graded coursework. Could you please provide some guidance. I am stuck. Thanks in advance for your help.
The problem statement is:
One of the confusing things about dictionaries is that they are unordered: the keys have no internal ordering to them. Sometimes though, you want to look through the keys in a
particular order, such as printing them alphabetically if they represent something like artist names.
For example, imagine if a forum tool used for a course exported its data as a dictionary. The keys of the dictionary are students' names, and the values are days of activity. Your goal is to return a list of students in the class in alphabetical order, followed by their days of activity, like this:
Chopra, Deepak: 22
Joyner, David: 14
Winfrey, Oprah: 17
Write a function named alphabetical_keys. alphabetical_keys should take as input a dictionary, and return a single string. The keys of the dictionary will be names and the values will be integers. The output should be a single string made of multiple
lines, following the format above: the name (the key), a colon and space, then the number of days of activity (the value), sorted alphabetically by key.
Remember, you are returning this as a single string: you're going to need to put the \n character after each line.
To convert a dictionary's keys into a list, use this line
of code:
keys_as_list = list(the_dict.keys)
From there, you could sort keys_as_list like any normal list.
Add your code here!
def alphabetical_keys(dictionary):
keys_as_list = list(dictionary.keys())
return keys_as_list + dictionary[keys]
Below are some lines of code that will test your function. You can change the value of the variable(s) to test your function with different inputs.
If your function works correctly, this will originally
print:
Chopra, Deepak: 22
Joyner, David: 14
Winfrey, Oprah: 17
the_dictionary = {"Joyner, David": 14, "Chopra, Deepak": 22, "Winfrey, Oprah": 17}
print(alphabetical_keys(the_dictionary))

While dictionaries may seem like they should be ordered, it's best not to think about them that way. It's a mapping from one thing to another.
You already have a way to get a list of the names in the dict:
keys_as_list = list(dictionary.keys())
After a quick Google search on "how to sort python list":
# sort list in place
keys_as_list.sort() # reverse=True would give reverse alpha order
Now you just need to loop through the sorted name as a way to access the dictionary keys:
return_str = "" # start with an empty string
for name in keys_as_list:
# add to the string -- get the name and the dict value for that name
return_str += f"{name}: {dictionary[name]}\n"
All together:
def alphabetical_keys(dictionary):
keys_as_list = list(dictionary.keys())
keys_as_list.sort()
return_str = ""
for name in keys_as_list:
return_str += f"{name}: {dictionary[name]}\n"
return return_str
d = {
"Chopra, Deepak": 22,
"Joyner, David": 14,
"Winfrey, Oprah": 17,
"Gump, Forrest": 9,
"Obama, Barack": 19,
}
string = alphabetical_keys(d)
print(string)
Output:
Chopra, Deepak: 22
Gump, Forrest: 9
Joyner, David: 14
Obama, Barack: 19
Winfrey, Oprah: 17

Related

How to add a value to a dictionary that has a duplicate key

I have this problem where I would like to add a value to a dictionary but the key is duplicate.
I would like the key to to hold a list with multiple values
this is what I have tried
def storingPassword():
username=("bob")#key,
password=("PASSWROD1")#value
allpasswords={
"jeff":"jeff 123 ",
"bob" : "bob 123"
}
if username not in allpasswords:
allpasswords[username]=password
else:
allpasswords[username].append(password)
return allpasswords
but i keep getting this error
"AttributeError: 'str' object has no attribute 'append'"
I expect a output something like this;
"jeff":"jeff 123 ",
"bob" : ["bob 123","PASSWORD1"]
That's because the value in your allpasswords dict is a string and you are trying to treat it like a list. Why are you trying to make your data structure complex with few values as list and few as string? I recommend to convert everything to list for a simpler logic.
Hence your code should be like this:
allpasswords={
"jeff": ["jeff 123 "],
"bob" : ["bob 123"]
}
allpasswords[username].append(password)
Instead of using dict object, you can use collections.defaultdict. It will let you define a dict with default value as list. So you don't need to even explicitly initialise value of new key as list. For example:
from collections import defaultdict
my_dict = defaultdict(list)
my_dict['new_key'].append('new_value')
# dictionary will hold the value:
# {'new_key': ['new_value']})
Initiate your dictionary entry with a list instead of just a string.
allpasswords[username] = [password] # List containing a single password
You will then be able to append to it.
(Having some entries contain a string while others contain a list of strings is best avoided - when it is time to look them up or print them, you would have to check each time whether it is a list or string.)

Classes vs. dictionaries as variable containers to get rid of quotation marks?

I’m trying to better understand the concept of python dictionaries and want to use a dictionary as a container of several variables in my code. Most examples I looked for, show strings as dictionary keys, which implies the use of quotation marks for using keys as variables. However, I found out that one does not need to use quotation marks if the key is firstly given a value and after that placed in a dictionary. Then one get rid of the quotation marks. The variable is then actually an immutable value. In that case, even as one changes the value of the key, the original value remains in the key and can be retrieved by dictionary method -.keys() (and thus be used to restore the first given value). However, I’m wondering if this is a proper way of coding and if it is better to apply a class as a variable container, which looks more simple but is perhaps slower when executed. Both approaches lead to the same result. See my example below.
class Container ():
def __init__(self):
self.a = 15
self.b = 17
# first given values
a = 5
b = 7
# dictionary approach
container = {a:15, b:17}
print('values in container: ', container[a], container[b])
container[a], container[b] = 25, 27
print('keys and values in container: ', container[a], container[b])
for key in container.keys():
print('firstly given values: ', key)
print('\n')
# class approach
cont = Container()
print('values in cont: ', cont.a, cont.b)
cont.a, cont.b = 25, 27
print('keys and values in cont: ', cont.a, cont.b)
However, I found out that one does not need to use quotation marks if the key is firstly given a value and after that placed in a dictionary.
This isn’t really what’s happening. Your code isn’t using 'a' and 'b' as dictionary keys. It’s using the values of the variables a and b — which happen to be the integers 5 and 7, respectively.
Subsequent access to the dictionary also happens by value: whether you write container[a] or container[5] doesn’t matter (as long as a is in scope and unchanged). But *it is not the same as container['a'], and the latter would fail here.
You can also inspect the dictionary itself to see that it doesn’t have a key called 'a' (or unquoted, a):
>>> print(dictionary)
{5: 15, 7: 17}
Ultimately, if you want to use names (rather than values) to access data, use a class, not a dictionary. Use a dictionary when the keys are given as values.
Later you may assign other values to a and b, and the code using dictionary will crash. Using a variable as a key is not a good practice. Do it with the class. You may also add the attributes to the constructor of your class.
class Container ():
def __init__(self, a, b):
self.a = a
self.b = b
# creating
cont = Container(15, 17)
# changin
cont.a, cont.b = 25, 27
I would recommand the class approach, because the dict approach in this case does not seem a proper way to code.
When you do :
a = 5
b = 7
container = {a:15, b:17}
You actually do :
container = {5:15, 7:17}
But this is "hidden", so there is a risk that later you reassign your variables, or that you just get confused with this kind of dictionary :
container = {
a:15,
b:17,
"a": "something"
}

Loop through dictionary keys to get values based on input

1) In my program I start with prompting a user for input.
2) I would then like to loop through the users input to get all the characters in that string, query each character individually against the dictionaries keys.
3) If a character from the input matches a key in the dictionary, I want that key's value returned.
4) This needs to be repeated for each character and the result should print those values returned in a string
To try and explain further, here is my dictionary:
dataDict = {
"a":"1",
"b":"2",
"c":"3",
}
For example:
If my input is abc, my result should be 123
If my input is cba, my result should be 321
and so on...
So far, this works if the string is only one character using the below code.
If i enter two characters, it just returns nothing.
dataInput=input("Enter stuff: ")
for key,value in dataDict.items():
if dataInput == key:
print(value)
How can I acheive the results i'm after?
You shouldn't be looping over the dict to find the matching keys, that's very inefficient. A dict is designed to do fast lookups: you give it the key and it gives you the value. Eg, dataDict["a"] results in "1".
Also, as Tim Pietzcker mentions, doing if dataInput == key will only work if dataInput consists of a single letter, because it compares the whole dataInput string to key.
Here's a simple way to do the desired conversion. We do the lookups in a list comprehension, which creates a list of the converted values, and then we pass that list to .join to create a string. (I've changed the names of your variables to conform with the PEP-008 style guide).
data_dict = {
"a": "1",
"b": "2",
"c": "3",
}
data_input = "aabbccba"
s = ''.join([data_dict[c] for c in data_input])
print(s)
output
11223321
However, that's not safe: it will fail with KeyError if data_input contains a char that's not in the dictionary. Here's a better way: it adds an empty string if it gets a bad char.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '') for c in data_input])
print(s)
output
11223321
Alternatively, we could convert bad data to some special value, eg 0.
data_input = "aaxbbcycbaz"
s = ''.join([data_dict.get(c, '0') for c in data_input])
print(s)
output
11022303210
Just for fun, here's a "functional" version. Guido would probably not approve of this one. :)
data_input = "aaxbbcycbaz"
print(''.join(filter(None, map(data_dict.get, data_input))))
11223321
You should be iterating over the input string, not the dictionary. Also, you might want to use .get() in case the users enters a characters that's not in the dictionary:
for letter in dataInput:
print(dataDict.get(letter,"X"))
This will print each letter on its individual line. If you want to print them in a single line, you can add the end="" parameter to the print function (and print an empty line after you're done).
The comparison you're doing would never work (in the first iteration, it would amount to if "abc" == "a", I hope that makes it obvious).
You're iterating through the wrong thing. You should be iterating through the input. You don't need to iterate through the dict, because you can just look up by key.

Iterate through Python Dictionary without knowing the specific keys

I can't seem to figure out how to write this piece of Python Code.
I need to read something in from a file, which is this:
Jake FJ49FJH
Bob FJ49GKH
I've imported the file into a dictionary. I then check if the number plate (following the names) contains the sequence of two letters, two numbers, then three letters. Here is that part of the code:
d = {} # Blank Dictionary
with open("plates.txt") as f:
d = dict(x.rstrip().split(None, 1) for x in f) # Put file into dictionary
names = d.keys()
print(names)
#carReg = ??
a,b,c = carReg[:2],carReg[2:4],carReg[4:]
if all((a.isalpha(),b.isdigit(),c.isalpha(),len(c)== 3)):
print("Valid Reg")
else:
print("Invalid Reg")
# Now get the name of the person with the invalid carReg
As you can see, I don't know what to put for carReg. I need to loop through the dictionary, like in a list when you can use an integer to get part of the list. If the program returns Invalid Reg, then I need to get the key that the invalid reg belongs to - which will be a name.
Any help appreciated.
Iterate over dict.items(); it'll give you the (key, value) pairs from the dictionary:
for name, car_registration in d.items():

From an (ID, number) pair keep only those pairs that contain the largest number

I am new in python and I would like some help for a small problem. I have a file whose each line has an ID plus an associated number. More than one numbers can be associated to the same ID. How is it possible to get only the ID plus the largest number associated with it in python?
Example:
Input: ID_file.txt
ENSG00000133246 2013 ENSG00000133246 540
ENSG00000133246 2010
ENSG00000253626 465
ENSG00000211829 464
ENSG00000158458 2577
ENSG00000158458 2553
What I want is the following:
ENSG00000133246 2013
ENSG00000253626 465
ENSG00000211829 464
ENSG00000158458 2577
Thanks in advance for any help!
I would think there are many ways to do this I would though use a dictionary
from collections import defaultdict
id_value_dict = defaultdict()
for line in open(idfile.txt).readlines():
id, value = line.strip().split()
if id not in id_value_dict:
id_value_dict[id] = int(value)
else:
if id_value_dict[id] < int(value):
id_value_dict[id] = int(value)
Next step is to get the dictionary written out
out_ref = open(outputfile.txt,'w')
for key, value in id_value_dict:
outref.write(key + '\t' + str(value)
outref.close()
There are slicker ways to do this, I think the dictionary could be written in a one-liner using a lamda or a list-comprehension but I like to start simple
Just in case you need the results sorted there are lots of ways to do it but I think it is critical to understand working with lists and dictionaries in python as I have found that the learning to think about the right data container is usually the key to solving many of my problems but I am still a new. Any way if you need the sorted results a straightforward was is to
id_value_dict.keys().sort()
SO this is one of the slick things about python id_value__dict.keys() is a list of the keys of the dictionary sorted
out_ref = open(outputfile.txt,'w')
for key in id_value_dict.keys():
outref.write(key + '\t' + str(id_value_dict[key])
outref.close()
its really tricky because you might want (I know I always want) to code
my_sorted_list = id_value_dict.keys().sort()
However you will find that my_sorted_list does not exist (NoneType)
Given that your input consists of nothing but contiguous runs for each ID—that is, as soon as you see another ID, you never see the previous ID again—you can just do this:
import itertools
import operator
with open('ID_file.txt') as idfile, open('max_ID_file.txt', 'w') as maxidfile:
keyvalpairs = (line.strip().split(None, 1) for line in idfile)
for key, group in itertools.groupby(keyvalpairs, operator.itemgetter(0)):
maxval = max(int(keyval[1]) for keyval in group)
maxidfile.write('{} {}\n'.format(key, maxval))
To see what this does, let's go over it line by line.
A file is just an iterable full of lines, so for line in idfile means exactly what you'd expect. For each line, we're calling strip to get rid of extraneous whitespace, then split(None, 1) to split it on the first space, so we end up with an iterable full of pairs of strings.
Next, we use groupby to change that into an iterable full of (key, group) pairs. Try printing out list(keyvalpairs) to see what it looks like.
Then we iterate over that, and just use max to get the largest value in each group.
And finally, we print out the key and the max value for the group.

Categories