Creating a Python dictionary - python

Is it possible to create a dictionary like this?
data = {(136-00000-0001 : 072-00000-0001,072-00000-0002,072-00000-0003),
(136-00000-0002 : 072-00000-0002,072-00000-0003,072-00000-0004)}
text = input("Put your 072-XXXXX-XXXX number in here: ")
wrapper =[]
for number in text:
if number in data.keys()
wrapper.append(data[number]
for w in wrapper:
print(w, end=" ")
I have a wrapper called 136-xxxxx-xxxx where 3*072-xxxxx-xxxx are in it.
All I want to do is, asking for a 072-xxxxx-xxxx number and the program is giving me
the Wrapper number of it back.
For example:
asking for 072-00000-0004
answer -> it´s inside 136-00000-0002
The only way I know is, for example that morse thing, where
morse = {"a":".-", "b":"-...", but is there a way like this for my example at the top?

You would need to store multiple values for your keys in a list,tuple etc.. You cannot have more than one value for a key.
data = {"136-00000-0001" : ["072-00000-0001","072-00000-0002","072-00000-0003"],"136-00000-0002" : ["072-00000-0002","072-00000-0003","072-00000-0004"]}
print ( data.values())
[['072-00000-0001', '072-00000-0002', '072-00000-0003'], ['072-00000-0002', '072-00000-0003', '072-00000-0004']]
To append to a keys values:
data["136-00000-0001"].append("whatever")
Check if value is in the dict and print the key,value pair.:
In [5]: for k,v in data.items():
if "072-00000-0004" in v:
print (k,v)
...:
136-00000-0002 ['072-00000-0002', '072-00000-0003', '072-00000-0004']
Use strings if you want use the format 072-00000-0002 will give an error SyntaxError: invalid token
.

In Python 2.x:
>>> data = {"136-00000-0001":["072-00000-0001","072-00000-0002","072-00000-0003"],"136-00000-0002":["072-00000-0002","072-00000-0003","072-00000-0004"]}
>>> text = raw_input("Put your 072-XXXXX-XXXX number in here: ")
Put your 072-XXXXX-XXXX number in here: 072-00000-0004
>>> for d in data:
... if text in data[d]:
... print d
136-00000-0002
And for Python 3 you have to use input() instead of raw_input() and print() as a function.
>>> data = {"136-00000-0001":["072-00000-0001","072-00000-0002","072-00000-0003"],"136-00000-0002":["072-00000-0002","072-00000-0003","072-00000-0004"]}
>>> text = input("Put your 072-XXXXX-XXXX number in here: ")
Put your 072-XXXXX-XXXX number in here: 072-00000-0004
>>> for d in data:
... if text in data[d]:
... print(d)
136-00000-0002

Related

sorted() function in python when reading a file sorts numbers by 1st digit only. I'm trying to print a high scores list in a python game

The code works as long as the numbers don't contain 0's. Otherwise it sorts like 9 is higher than 10 for example.
def enter_high_score():
print()
name=input("Please Enter You Name: ")
file=open("score.txt", "a")
file.write(str(9000) +"\t" +(name)+ "\n")
file.close()
file=open("score.txt", "r")
readthefile = file.readlines()
sorted_scores = sorted(readthefile,reverse=True)
print("Top 5 Scores!")
print("Pos\tPoints\tName")
for line in range(5):
# print(str(sortedData[line])+"\t"+str(line+1))
print(str(line+1)+"\t"+str(sorted_scores[line]))
Vahid is right with their answer, but there's no need to seperate that digit out and create a list of tuples to sort based on the first word in the line as an integer. We can just extract that info directly in the call to sorted.
>>> data = """15 hello
... 9 world
... 3 foo bar"""
>>> lines = data.split('\n')
>>> sorted(lines, key=lambda line: int(line.split(' ', 1)[0]))
['3 foo bar', '9 world', '15 hello']
>>>
I figured out a work around as I'm not quite up to the level as mentioned above.
So basically, I've created some if statements saying that;
if number is within a certain range say 999 - 1000 for example add "00" to the front.
So my scores read 00100
00010
00001
for example... and if it's over any of those specified values there's an else statement goin "woah you scored off the charts your so good!"
name = input("Please Enter You Name: ")
# note that you are appending to the file and at line 5 writing same score every time
file = open("score.txt", "a")
# use Python f-string
file.write(f"9000\t{name}\n")
file.close()
file = open("score.txt", "r")
lines = file.readlines()
# For each line create a list of tuples of (int, str), e.g. [(200,John)]
records = list(map(lambda line: (int(line.split()[0]), line.split()[1]), lines))
# Highest first, key is saying sort based on first item in (int, str) which is the score
sorted_records = sorted(records, key=lambda r: r[0], reverse=True)
print(sorted_records)

Python Zipfile read file and output each line instead of text block? [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Pass arguments to Print [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Recursively create a nested dictionary from string [duplicate]

This question already has answers here:
Converting list to nested dictionary
(4 answers)
Closed 5 years ago.
I have an issue that I've been trying to sort out. I have a string that needs to be converted to an nested dictionary with the keys and values based off the adjacent words in the string. Here is an example:
graphMaster = {}
inputSentence = "I have a dog named Max."
I would like to take this string, and convert it into a dictionary resembling the output below:
print graphMaster
{'I': {'have': {'a': {'dog': {'named': 'Max'}}}}}
I have tried the following:
graphMaster = {}
inputSentence = "I have a dog named Max."
while True:
inputList = inputSentence.strip().split(' ')
for currentIndex, word in enumerate(inputList):
nextIndex = currentIndex + 1
if nextIndex < len(inputList):
if word not in graphMaster.keys():
graphMaster[word] = inputList[nextIndex]
elif word in graphMaster.keys():
break
print graphMaster
I couldn't find a duplicate problem here and I pre-apologize if one exists that I couldn't find. Any help is greatly appreciated.
You could do something like this:
outdict = {}
curdict = outdict
for f in inputSentence.split(' '):
curdict[f] = {}
curdict = curdict[f]
print outdict
Where curdict is only pointing to a location in the output dictionary.

Why can't I search through the dictionary I created (Python)?

In this program I am making a dictionary from a plain text file, basically I count the amount a word occurs in a document, the word becomes the key and the amount of time it occurs is the value. I can create the dictionary but then I cannot search through the dictionary. Here is my updated code with your guys' input. I really appreciate the help.
from collections import defaultdict
import operator
def readFile(fileHandle):
d = defaultdict(int)
with open(fileHandle, "r") as myfile:
for currline in myfile:
for word in currline.split():
d[word] +=1
return d
def reverseLookup(dictionary, value):
for key in dictionary.keys():
if dictionary[key] == value:
return key
return None
afile = raw_input ("What is the absolute file path: ")
print readFile (afile)
choice = raw_input ("Would you like to (1) Query Word Count (2) Print top words to a new document (3) Exit: ")
if (choice == "1"):
query = raw_input ("What word would like to look up? ")
print reverseLookup(readFile(afile), query)
if (choice == "2"):
f = open("new.txt", "a")
d = dict(int)
for w in text.split():
d[w] += 1
f.write(d)
file.close (f)
if (choice == "3"):
print "The EXIT has HAPPENED"
else:
print "Error"
Your approach is very complicated (and syntactically wrong, at least in your posted code sample).
Also, you're rebinding the built-in name dict which is problematic, too.
Furthermore, this functionality is already built-in in Python:
from collections import defaultdict
def readFile(fileHandle):
d = defaultdict(int) # Access to undefined keys creates a entry with value 0
with open(fileHandle, "r") as myfile: # File will automatically be closed
for currline in myfile: # Loop through file line-by-line
for word in currline.strip().split(): # Loop through words w/o CRLF
d[word] +=1 # Increase word counter
return d
As for your reverseLookup function, see ypercube's answer.
Your code returns after it looks in the first (key,value) pair. You have to search the whole dictionary before returning that the value has not been found.
def reverseLookup(dictionary, value):
for key in dictionary.keys():
if dictionary[key] == value:
return key
return None
You should also not return "error" as it can be a word and thus a key in your dictionary!
Depending upon how you're intending to use this reverseLookup() function, you might find your code much happier if you employ two dictionaries: build the first dictionary as you already do, and then build a second dictionary that contains mappings between the number of occurrences and the words that occurred that many times. Then your reverseLookup() wouldn't need to perform the for k in d.keys() loop on every single lookup. That loop would only happen once, and every single lookup after that would run significantly faster.
I've cobbled together (but not tested) some code that shows what I'm talking about. I stole Tim's readFile() routine, because I like the look of it more :) but took his nice function-local dictionary d and moved it to global, just to keep the functions short and sweet. In a 'real project', I'd probably wrap the whole thing in a class to allow arbitrary number of dictionaries at run time and provide reasonable encapsulation. This is just demo code. :)
import operator
from collections import defaultdict
d = defaultdict(int)
numbers_dict = {}
def readFile(fileHandle):
with open(fileHandle, "r") as myfile:
for currline in myfile:
for word in currline.split():
d[word] +=1
return d
def prepareReverse():
for (k,v) in d.items():
old_list = numbers_dict.get(v, [])
new_list = old_list << k
numbers_dict[v]=new_list
def reverseLookup(v):
numbers_dict[v]
If you intend on making two or more lookups, this code will trade memory for execution speed. You only iterate through the dictionary once (iteration over all elements is not a dict's strong point), but at the cost of duplicate data in memory.
The search is not working because you have a dictionary mapping a word to its count, so getting the number of occurrences for a 'word' should be just dictionary[word]. You don't really need the reveseLookup(), there is already a .get(key, default_value) method in dict: dictionary.get(value, None)

Categories