Convert String to Dictionary - python

I have a string
str = "Name John"
I want to change it to a dictionary.
{"Name":"John"}
How do I achieve this?
I Have tried using comprehension but I get an error.
str = "Arjun 23344"
Name = {str.split()}
Error
Traceback (most recent call last):
File "/home/daphney/Python/AGame.py", line 2, in <module>
Name = {x.split()}
TypeError: unhashable type: 'list'

You can split:
my_dict = {str.split(" ")[0]:str.split(" ")[1]}
Note: If you have, say, Name John Smith and want the dict to be Name:Smith, then you can just change the [1] to [-1] to get the last indexed item.

You can create a dictionary using dict function by providing list of [key,value] lists (or (key,value) tuples):
my_str = "Arjun 23344"
Name = dict([my_str.split()])
print(Name) # output: {'Arjun': '23344'}

Name = dict([str.split()])
This would only work if your string always splits into exactly two words. This works because the split call returns a list of two elements, which is then stored inside a containing list, and passed to the dict constructor. The latter can work properly with a sequence (list or other) of pairs (lists or other).
This works in this particular case, but is not robust or portable.

As there are only two strings in your variable.
string = "Name Shivank"
k,v = string.split()
d = dict()
d[k] = v
print(d) #output: {'Name':'Shivank'}

you can provide a second parameter to the split function to limit the number of separations (to 1 in this case):
dict([string.split(" ",1)])

Related

accessing nested dictionaries when you know the nested key?

This one is probably pretty easy, but I can't figure it out! Suppose I have a dictionary with a nested dictionary, that I know the nested dictionary key that I can store in a variable, how would I access this value?
k = 'mynested'
nestedk = 'blah'
x = {}
x['mynested'] = {}
x['mynested']['blah'] = 1
print(x[k[nestedk]])
throws error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string indices must be integers
There is a slight mistake in your last line print(x[k[nestedk]]). This line actually means that you are treating the k variable as a list which is actually a string and the characters of the string can only be accessed by an integer index and not by a string index.
Change the last line to the below
print(x[k][nestedk])
You can get it with x[k][nestedk]. You can access the values similar to assigning values inside dictionary. As you are assigning
X[k] = {}
and x[k][nestedk] = 1
The value is 1 and key for nested object is k so initially we get the inner dictionary by x[k] and then we get the value using nested key in your case nestedk.
Thus you have to correct your print statement like below
print(x[k][nestedk])

Sorting list of strings by a character

I got the following assignment:
For a given list of strings write a function that returns a sorted list with all strings starting with the character x at the beginning (define two lists)
I stuck here:
set_words_list = ["argentinax", "football", "ss", "poxland", "axmerica"]
set_words_list.sort(key=str("x"))
print(set_words_list)
And then error pops out:
Traceback (most recent call last):
File "/5SortList/main.py", line 7, in <module>
set_words_list.sort(key=str("x"))
TypeError: 'str' object is not callable
It is my first time coding in Python, and I have no clue where to go from there.
On top of that, according to the task one needs to use 2 lists, yet I don't know how it can help me.
The simplest way is to split the input into two lists. One contains the elements that start with x, the other contains the rest. That's what the instructions meant by "define two lists".
Then sort each of these lists and concatenate them.
x_words = []
nox_words = []
for word in set_words_list:
if word.startswith("x"):
x_words.append(word)
else:
nox_words.append(word)
result = sorted(x_words) + sorted(nox_words)
list.sort(reverse=True|False, key=myFunc)
reverse --> Optional. reverse=True will sort the list descending. Default is reverse=False
key--> Optional. A function to specify the sorting criteria(s)
In below code we are passing myFunc to the key part of the sort function.
Function returns not e.startswith('x') since True == 1. This will sort the words starting with 'x'.
def myFunc(e):
return not e.startswith('x')
set_words_list = ["argentinax", "football", "ss", "poxland", "axmerica", 'xx']
set_words_list.sort(key=myFunc)
print(set_words_list)
set_words_list = ["argentinax", "football", "ss", "poxland", 'xamerica' ,"axmerica"]
x_first_letter = sorted([x for x in set_words_list if x[0]=='x'])
nox_first_letter = sorted([x for x in set_words_list if not x[0]=='x'])

Why am I getting an error of unhashable type:'list' in the following code.

I was trying to make the wordcount program.
But, I am getting stuck on it. Please check what is the fault, i have also marked the error line.
def print_words(filename):
f=open(filename,'rU')
text=f.read()
count={}
for var in text:
var=var.lower()
var=var.split()
if not var in count: // Error Line
count[var]=1
else:
count[var]=count[var]+1
return count
Thanks
Because var is a list and you are trying to use it as a key in a dictionary.
Lists are unhashable because they are mutable.
Turn var to a tuple (tuple(var)) or re-think your code.
you convert var to list: var=var.split(). so you can use in for checking. instead you should use for.
Also It's better to use defaultdict for this jobs.
from collections import defaultdict
...
count=defaultdict(int)
for var in text:
var=var.lower()
for intem in var.split():
count[item]+=1
print count
List is a mutable type which cannot be hashed. Refer hashable from which I am quoting the relevant part
Hashability makes an object usable as a dictionary key and a set
member, because these data structures use the hash value internally.
All of Python’s immutable built-in objects are hashable, while no
mutable containers (such as lists or dictionaries) are.
A non hashable type cannot be used as a dictionary key but in your case str.split() generates a list which you are trying to use as a key. A simple solution would be to convert it to a non mutable sequence like tuple
count[tuple(var)]=1
As there are multiple cases where you have used var as-is, it is recommend to wrap it with a tuple built-in to convert it as a tuple before using it as a key to a dictionary
var=tuple(var.split())
Here, count is a dictionary. And finally, var is a list.
if not var in count:
This line checks if a list exists among the dictionary keys. But a list isn't hashable because you can mutate it. But hashability is a prerequisite of being a dictionary key. That's why the error.
Error regeneration:
>>> a=[1,3,4]
>>> b={}
>>> a not in b
Traceback (most recent call last):
File "", line 1, in
TypeError: unhashable type: 'list'
You can solve it this way:
def print_words(filename):
with open(filename,'rU') as f:
count={}
for line in f:
for word in line.lower().split():
if word not in count:
count[word] = 1
else:
count[word] += 1
return count

Python3: Calling functions saved as values (strings) in a dictionary

Background:
I am reading a python file (.py) that has a number of functions defined and using a regex to get the names of all the functions and store them in a list.
d_fncs = {}
list_fncs = []
with open('/home/path/somefile.py', 'r') as f:
for row in f:
search = re.search(r'def (.*)\(', row)
if search:
list_fncs.append(search.group(1))
The above works fine and as expected returns a list of of the function names as strings. I have another list which I plan to use as a counter.
counter = [str(i) for i in range(1,len(list_fncs)+1)]
Finally, I zip the two lists to get a dictionary where the 'keys' are numbers and the associated 'values' are function names
d_fncs = dict(zip(counter,list_fncs))
The problem:
The intent here is to ask user for an input which would be matched with the key of this dictionary (counter). Once the key is matched, the function associated with it is executed. Something like this happens later in the code:
def option_to_run(check, option_enter_by_user):
if check == 'True':
return (connection(d_fncs[option]))
def connection(fnc):
conn_name = Connect(some args..) #class imported
fnc(conn_name)
In this case, as the values from dict are string, I get the following error:
File "/home/path/filename.py", line 114, in connection
fnc(conn_name)
TypeError: 'str' object is not callable
However, if I manually make a dict and run it then I have no issues and functions work as expected:
d_fncs_expected = {'1': function1, '2': function2, ....}
Right now what I am getting is this:
d_fncs = {'1': 'function1', '2': 'function2', ....}
....what can I do to get the dictionary to work in a way so I can call these functions? I want the values not to be strings but a type:class
Replace
fnc(conn_name)
to
eval(fnc)(conn_name) # or eval(fnc(conn_name))
or
globals()[fnc](conn_name)
For example
def myfn(arg):
print(arg +" is printed")
d = {1: 'myfn'}
fun_name = d[1] # 'myfn'
>>>fun_name("something")
TypeError: 'str' object is not callable
>>>eval(fun_name)("something")
something is printed
>>>globals()[fun_name]("someting")
something is printed

how to make my list to append different type data in python?

The list in python can load different type of data.
>>> x=[3,4,"hallo"]
>>> x
[3, 4, 'hallo']
How can i define a multi-dim list to load different type of data?
>>> info=['']*3
>>> info[0].append(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'append'
I want to make info to be a multi-dim list,info[0] can load character and number.
Create an empty list of lists first:
info = [[] for _ in range(3)]
info[0].append(2)
info[1].append("test")
info will then look like:
[[2], ['test'], []]
Quite simply you are trying to append to a string that happens to be contained in a list. But you can't append to a string (string concatenation is something else). So either use string concatenation (if that was what you intended), or use an empty list as a container inside the list.
l = [[],[]]
is a list with two elements, two empty lists.
l.append('something')
gives you
[[],[],'something']
but l[0].append('something') would have given you:
[['something'],[]]
Instead of append, do it as follows:
>>> info=['']*3
>>> info[0] += '2' #if you want it stored as a string
Or
>>> info[0] = int(info[0]+'2') #if you want it stored as an int

Categories

Resources