l = {}
name = [(str, input().split()) for i in range(0, 15)]
dob = [(int, input().split()) for i in range(0, 15)]
print({name[i]:dob[i] for i in range(len(dob))})
I want to print 15 items in a dictionary format of name as key and dateofbirth(dob) as value.What wrong I am doing?
.....................................................................................
the error is:
Traceback (most recent call last):
File "main.py", line 4, in <module>
print({name[i]:dob[i] for i in range(len(dob))})
File "main.py", line 4, in <dictcomp>
print({name[i]:dob[i] for i in range(len(dob))})
TypeError: unhashable type: 'list'
The issue is not in the print() function but in the way you make up the first list: instead of pulling out the names, it gives you a (<class 'str'>, 'string') tuple that cannot be used as a key for a dictionary. The same happens with the 'dob' variable, but the issue is only with keys.
Try doing:
name = [input() for i in range(0, 15)] #this takes and returns the input. no need to convert to string
dob = [int(input()) for i in range(0, 15)] #this takes an input and returns it's numeric value
I would do it like this (this returns a generator):
name = map(str, input().split())
dob = map(int, input().split())
print({n: d for n, d in zip(name, dob)})
If you want it to return a list instead:
name = list(map(str, input().split()))
dob = list(map(int, input().split()))
print({n: d for n, d in zip(name, dob)})
Related
Alien Dictionary
Link to the online judge -> LINK
Given a sorted dictionary of an alien language having N words and k starting alphabets of standard dictionary. Find the order of characters in the alien language.
Note: Many orders may be possible for a particular test case, thus you may return any valid order and output will be 1 if the order of string returned by the function is correct else 0 denoting incorrect string returned.
Example 1:
Input:
N = 5, K = 4
dict = {"baa","abcd","abca","cab","cad"}
Output:
1
Explanation:
Here order of characters is
'b', 'd', 'a', 'c' Note that words are sorted
and in the given language "baa" comes before
"abcd", therefore 'b' is before 'a' in output.
Similarly we can find other orders.
My working code:
from collections import defaultdict
class Solution:
def __init__(self):
self.vertList = defaultdict(list)
def addEdge(self,u,v):
self.vertList[u].append(v)
def topologicalSortDFS(self,givenV,visited,stack):
visited.add(givenV)
for nbr in self.vertList[givenV]:
if nbr not in visited:
self.topologicalSortDFS(nbr,visited,stack)
stack.append(givenV)
def findOrder(self,dict, N, K):
list1 = dict
for i in range(len(list1)-1):
word1 = list1[i]
word2 = list1[i+1]
rangej = min(len(word1),len(word2))
for j in range(rangej):
if word1[j] != word2[j]:
u = word1[j]
v = word2[j]
self.addEdge(u,v)
break
stack = []
visited = set()
vlist = [v for v in self.vertList]
for v in vlist:
if v not in visited:
self.topologicalSortDFS(v,visited,stack)
result = " ".join(stack[::-1])
return result
#{
# Driver Code Starts
#Initial Template for Python 3
class sort_by_order:
def __init__(self,s):
self.priority = {}
for i in range(len(s)):
self.priority[s[i]] = i
def transform(self,word):
new_word = ''
for c in word:
new_word += chr( ord('a') + self.priority[c] )
return new_word
def sort_this_list(self,lst):
lst.sort(key = self.transform)
if __name__ == '__main__':
t=int(input())
for _ in range(t):
line=input().strip().split()
n=int(line[0])
k=int(line[1])
alien_dict = [x for x in input().strip().split()]
duplicate_dict = alien_dict.copy()
ob=Solution()
order = ob.findOrder(alien_dict,n,k)
x = sort_by_order(order)
x.sort_this_list(duplicate_dict)
if duplicate_dict == alien_dict:
print(1)
else:
print(0)
My problem:
The code runs fine for the test cases that are given in the example but fails for ["baa", "abcd", "abca", "cab", "cad"]
It throws the following error for this input:
Runtime Error:
Runtime ErrorTraceback (most recent call last):
File "/home/e2beefe97937f518a410813879a35789.py", line 73, in <module>
x.sort_this_list(duplicate_dict)
File "/home/e2beefe97937f518a410813879a35789.py", line 58, in sort_this_list
lst.sort(key = self.transform)
File "/home/e2beefe97937f518a410813879a35789.py", line 54, in transform
new_word += chr( ord('a') + self.priority[c] )
KeyError: 'f'
Running in some other IDE:
If I explicitly give this input using some other IDE then the output I'm getting is b d a c
Interesting problem. Your idea is correct, it is a partially ordered set you can build a directed acyclcic graph and find an ordered list of vertices using topological sort.
The reason for your program to fail is because not all the letters that possibly some letters will not be added to your vertList.
Spoiler: adding the following line somewhere in your code solves the issue
vlist = [chr(ord('a') + v) for v in range(K)]
A simple failing example
Consider the input
2 4
baa abd
This will determine the following vertList
{"b": ["a"]}
The only constraint is that b must come before a in this alphabet. Your code returns the alphabet b a, since the letter d is not present you the driver code will produce an error when trying to check your solution. In my opinion it should simply output 0 in this situation.
I found this thread how to make a variable change from the text "1m" into "1000000" in python
My string values are in a column within a pandas dataframe. The string/0bkects values are like 18M, 345K, 12.9K, 0, etc.
values = df5['Values']
multipliers = { 'k': 1e3,
'm': 1e6,
'b': 1e9,
}
pattern = r'([0-9.]+)([bkm])'
for number, suffix in re.findall(pattern, values):
number = float(number)
print(number * multipliers[suffix])
Running the code gives this error:
Traceback (most recent call last):
File "c:/Users/thebu/Documents/Python Projects/trading/screen.py", line 19, in <module>
for number, suffix in re.findall(pattern, values):
File "C:\Users\thebu\Anaconda3\envs\trading\lib\re.py", line 223, in findall
return _compile(pattern, flags).findall(string)
TypeError: expected string or bytes-like object
Thanks
Here's another way using regex:
import re
def get_word(s):
# find word
r = re.findall(r'[a-z]', s)
# find numbers
w = re.findall(r'[0-9]', s)
if len(r) > 0 and len(w) > 0:
r = r[0]
v = multipliers.get(r, None)
if v:
w = int(''.join(w))
w *= v
return round(w)
df['col2'] = df['col'].apply(get_word)
print(df)
col col2
0 10k 10000
1 20m 20000000
Sample Data
df = pd.DataFrame({'col': ['10k', '20m']})
d =dict(input('Enter a dictionary'))
sum = 0
for i in d.values():
sum +=i
print(sum)
outputs: Enter a dictionary{'a': 100, 'b':200, 'c':300}
this is the problem arises:
Traceback (most recent call last):
File "G:/DurgaSoftPython/smath.py", line 2, in <module>
d =dict(input('Enter a dictionary'))
ValueError: dictionary update sequence element #0 has length 1; 2 is required
You can't create a dict from a string using the dict constructor, but you can use ast.literal_eval:
from ast import literal_eval
d = literal_eval(input('Enter a dictionary'))
s = 0 # don't name your variable `sum` (which is a built-in Python function
# you could've used to solve this problem)
for i in d.values():
s +=i
print(s)
Output:
Enter a dictionary{'a': 100, 'b':200, 'c':300}
600
Using sum:
d = literal_eval(input('Enter a dictionary'))
s = sum(d.values())
print(s)
import json
inp = input('Enter a dictionary')
inp = dict(json.loads(inp))
sum = sum(inp.values())
print(sum)
input Enter a dictionary{"a": 100, "b":200, "c":300}
output 600
Actually the return of input function is a string. So, in order to have a valid python dict you need to evaluate the input string and convert it into dict.
One way to do this can be done using literal_eval from ast package.
Here is an example:
from ast import literal_eval as le
d = le(input('Enter a dictionary: '))
_sum = 0
for i in d.values():
_sum +=i
print(_sum)
Demo:
Enter a dictionary: {'a': 100, 'b':200, 'c':300}
600
PS: Another way can be done using eval but it's not recommended.
I am new to python3 and tring to build a sqlobject class which named whatever. Then I created a function to caculate the average of one column. Here are parts of the codes.
class whatever(sqlobject.SQLObject):
_connection = connection
f1 = sqlobject.FloatCol()
f2 = sqlobject.FloatCol()
wid=sqlobject.IntCol(default=None)
def avg(col, num):
l1 = []
for i in range(1,num):
e = whatever.get(i).col
l1.append(a)
return statistics.mean(l1)
print (avg(f1, 5))
But it returns the error:
Traceback (most recent call last):
File "test1.py", line 58, in <module>
print (avg(f1, 5))
NameError: name 'f1' is not defined
However, when I directly wrote down the code like this:
class whatever(sqlobject.SQLObject):
_connection = connection
f1 = sqlobject.FloatCol()
f2 = sqlobject.FloatCol()
wid=sqlobject.IntCol(default=None)
l1 = []
for i in range(1,5):
e = whatever.get(i).f1
l1.append(e)
print (statistics.mean(l1))
It works fine. So what should I do with the def avg(col, num) function?
Please note that whatever.get(i).f1 works — this because you name the column explicitly. If you want to get a column by name you have to:
pass the name of the column, i.e. avg('f1', 5);
get the value for the column using getattr.
So the fixed code is:
def avg(col, num):
l1 = []
for i in range(1, num):
e = getattr(whatever.get(i), col)
l1.append(a)
return statistics.mean(l1)
print(avg('f1', 5))
PS. The next error in your code will be NameError: a. What is a? Do you mean e?
I'm trying to make a program that will pick up randomly a name from a file. The user would be asked if he wants to pick up another one again (by pressing 1).
The names can't be picked up twice.
Once picked up, the names would be stocked in a list, written into a file.
When all the names are picked up, the program would be able to restart from the beginning.
I checked other similar problems, but I still don't get it...
from random import *
#import a list of name from a txt file
def getL1():
l1 = open("Employees.txt", "r")
list1 = []
x = 0
for line in l1:
list1.append(line)
x = x+1
list1 = [el.replace('\n', '') for el in list1]
#print("list" 1 :",list)
return list1
#import an empty list (that will be filled by tested employees) during
#execution of the program
def getL2():
l2 = open("tested.txt", "r")
list2 = []
for line in l2:
list2.append(line)
list2 = [el.replace('\n', '') for el in list2]
#print("list 2 :",list2)
l2.close()
return list2
def listCompare():
employees = getL1()#acquire first list from employee file
tested = getL2()#acquire second list from tested file
notTested = []# declare list to hole the results of the compare
for val in employees:
if val not in tested: #find employee values not present in tested
#print(val)
notTested.append(val)#append value to the notTested list
return notTested
def listCount():
x=0
employees = getL1()
tested = getL2()
for val in employees:
if val not in tested:
x = x+1
return x
#add the names of tested employees the the second second file
def addTested(x):
appendFile = open("tested.txt", "a")
appenFile.write(x)
appendFile.write('\n')
appendFile.close()
def main():
entry = 1
while entry == 1:
pickFrom = listCompare()
if listCount() > 0:
y = randint (0, (listCount ()-1))
print ('\n' + "Random Employee to be tested is: ", pickFrom(y), "\n")
addTested(pickFrom[y])
try:
entry = int(input("Would you like to test another employee? Enter 1:"))
except:
print("The entry must be a number")
entry = 0
else:
print("\n/\ new cycle has begun")
wipeFile = open("tested.txt", "w")
print ("goodbye")
main()
The last error that I have is :
Traceback (most recent call last):
File "prog.py", line 78, in <module>
main()
File "prog.py", line 65, in main
print ('\n' + "Random Employee to be tested is: ", pickFrom(y), "\n")
TypeError: 'list' object is not callable
As per the code print pickFrom is a list and when you are referencing it in the print it needs to be called using [ ]. Change it to pickFrom[y]