im given the following input:
'family': 'man: name, woman: name, child: name , grandma: name, grandpa: name'
where 'family' is a key, and its value is a bunch of other key-value pairs. as you can tell, you cant parse it using json() because this string is not structured in json format. ive been trying for hours to parse this string into a dictionary/json valid string so i could work with it properly and change name values accordingly. would appreciate the help.
Assuming that no key and no value ever contains a comma or a colon, you could do this:
def split_to_dict(string: str) -> dict[str, str]:
output = {}
for pair in string.split(','):
key, value = pair.split(':')
output[key.strip()] = value.strip()
return output
Calling it like this:
s = 'man: name, woman: name, child: name , grandma: name, grandpa: name'
d = split_to_dict(s)
print(d)
gives the following:
{'man': 'name', 'woman': 'name', 'child': 'name', 'grandma': 'name', 'grandpa': 'name'}
For readability purposes, I would refrain from doing this in a dictionary comprehension.
You first need to convert it to a correct json.
d = {'family': 'man: name, woman: name, child: name , grandma: name, grandpa: name'}
d['family'] = re.sub("(\w+)", r'"\1"', d['family'])
# now parse it
json.loads("{" + d['family'] + "}")
Assuming the input is loaded in as a dictionary and we want to turn the value of family into a corresponding dictionary of key-value pairs. We can do that by doing some string processing as such:
>>> d = {'family': 'man: name, woman: name, child: name , grandma: name, grandpa: name'}
>>> d['family'] = { x.split(':')[0] : x.split(':')[1].strip() for x in d['family'].split(', ')}
>>>
>>> d['family']
>>> {'man': 'name','woman': 'name', 'child': 'name', 'grandma': 'name', 'grandpa': 'name'}
We first split the value of family into key-value strings, and then we further split each key-value string to turn it into the corresponding key-value pair in the list comprehension of the new dictionary.
Related
I am trying to pass a data back to a URL fetch request. We are using Python 3.x
user_type_data = {'user_type': 'admin',
'user_name': 'myname',
'user_check_flag': 'yes'}
return_data = json.dumps({
l_user_type_data : user_type_data
},default = date_handler)
return return_data
When we do this for a dict I am getting the following error - TypeError("unhashable type: 'dict'"). According to this, it states that we cannot use a dict that is not hashabale - but how do we do this?
How do we fix this?
A valid dictionary key string should be enveloped by quotes or double quotes.
a_dict = {'key': 'value'} # Valid
b_dict = {"key": "value"} # Valid
Or if you wish to assign string that was stored in a variable to be the dictionary key, you can do this instead:
st = "key"
a_dict = dict()
a_dict[st] = 'value'
Since json_dumps requires a valid python dictionary, you may need to rearrange your code.
If the l_user_type_data is a variable contains a string, you should do:
temp_dict = dict()
temp_dict[l_user_type_data] = user_type_data
result = json.dumps(temp_dict, default = date_handler)
Otherwise, if l_user_type_data is a string for the key, just simply enclose that with either single quote or double quotes.
return_data = json.dumps({
"l_user_type_data" : user_type_data
},default = date_handler)
I came across this recursive function that's supposed flatten a dictionary:
def flatten(data, prefix='', separator='.'):
"""Flattens a nested dict structure. """
if not isinstance(data, dict):
return {prefix: data} if prefix else data
result = {}
for (key, value) in data.items():
result.update(flatten(value,_get_new_prefix(prefix, key, separator),
separator=separator))
return result
def _get_new_prefix(prefix, key, separator):
return (separator.join((prefix, str(key))) if prefix else str(key))
it's also supposed to be fed with this data:
nested = {
'fullname': 'Alessandra',
'age': 41,
'phone-numbers': ['+447421234567', '+447423456789'],
'residence': {'address': {'first-line': 'Alexandra Rd','second-line': '',},
'zip': 'N8 0PP',
'city': 'London',
'country': 'UK',
},
}
I'm trying to figure out how it works and particularly how the "prefix" parameter works and in what case it will not be empty.
The flatten() function builds the path down the tree, where the names in the path are separated by the separator. The prefix is added to the beginning of that path.
prefix is only "empty" if you set it to None. That will have the effect of suppressing the prefix.
For example, compare the output of this:
[print(k, ' = ', v) for k,v in flatten(nested, prefix='xxx', separator='/').items()]
...with this:
[print(k, ' = ', v) for k,v in flatten(nested, prefix=None).items()]
I was trying to split combination of string, unicode in python. The split has to be made on the ResultSet object retrieved from web-site. Using the code below, I am able to get the details, actually it is user details:
from bs4 import BeautifulSoup
import urllib2
import re
url = "http://www.mouthshut.com/vinay_beriwal"
profile_user = urllib2.urlopen(url)
profile_soup = BeautifulSoup(profile_user.read())
usr_dtls = profile_soup.find("div",id=re.compile("_divAboutMe")).find_all('p')
for dt in usr_dtls:
usr_dtls = " ".join(dt.text.split())
print(usr_dtls)
The output is as below:
i love yellow..
Name: Vinay Beriwal
Age: 39 years
Hometown: New Delhi, India
Country: India
Member since: Feb 11, 2016
What I need is to create distinct 5 variables as Name, Age, Hometown, Country, Member since and store the corresponding value after ':' for same.
Thanks
You can use a dictionary to store name-value pairs.For example -
my_dict = {"Name":"Vinay","Age":21}
In my_dict, Name and Age are the keys of the dictionary, you can access values like this -
print (my_dict["Name"]) #This will print Vinay
Also, it's nice and better to use complete words for variable names.
results = profile_soup.find("div",id=re.compile("_divAboutMe")).find_all('p')
user_data={} #dictionary initialization
for result in results:
result = " ".join(result.text.split())
try:
var,value = result.strip().split(':')
user_data[var.strip()]=value.strip()
except:
pass
#If you print the user_data now
print (user_data)
'''
This is what it'll print
{'Age': ' 39 years', 'Country': ' India', 'Hometown': 'New Delhi, India', 'Name': 'Vinay Beriwal', 'Member since': 'Feb 11, 2016'}
'''
You can use a dictionary to store your data:
my_dict = {}
for dt in usr_dtls:
item = " ".join(dt.text.split())
try:
if ':' in item:
k, v = item.split(':')
my_dict[k.strip()] = v.strip()
except:
pass
Note: You should not use usr_dtls inside your for loop, because that's would override your original usr_dtls
Need to write a function that takes an open file as the only parameter and returns a dictionary that maps a string to a list of strings and integers.
each line in the text will have a username, first name, last name, age, gender and an e-mail address. The function will insert each person's information into a dictionary with their username as the key, and the value being a list of [last name, first name, e-mail, age, gender].
basically what im trying to do is open a text file that contains this:
ajones Alice Jones 44 F alice#alicejones.net
and return something like this:
{ajones: ['Jones', 'Alice', 'alice#alicejones.net', 44, 'F']}
so far i have done this, but is there any other easier way?
def create_dict(file_name):
'''(io.TextIOWrapper) -> dict of {str: [str, str, str, int, str]}
'''
newdict = {}
list2 = []
for line in file_name:
while line:
list1 = line.split() #for a key, create a list of values
if list2(0):
value += list1(1)
if list2(1):
value += list1(2)
if list2(2):
value += list1(3)
if list2(3):
value += list1(4)
newdict[list1(0)] = list2
for next_line in file_name:
list1 = line.split()
newdict[list1(0)] = list1
return newdict
def helper_func(fieldname):
'''(str) -> int
Returns the index of the field in the value list in the dictionary
>>> helper_func(age)
3
'''
if fieldname is "lastname":
return 0
elif fieldname is "firstname":
return 1
elif fieldname is "email":
return 2
elif fieldname is "age":
return 3
elif fieldname is "gender":
return 4
If you have Python 2.7+, you can use a dictionary comprehension:
{l[0]: l[1:] for l in (line.rstrip().split(' ') for line in f)}
for line in file_name:
lineData = line.split() #for a key, create a list of values
my_dict[lineData[0]] = lineData[1:]
is a little easier i think ... although Im not sure if thats doing what you want ...
Agree with the first answer, here is the slightly different version to match the spec:
file=open('filename', 'r')
{username: [lname, fname, email, int(age), sex] for username, fname, lname, age, sex, email in (line.rstrip().split(' ') for line in file)}
There are certainly easier ways to build your dictionary:
d={}
st='ajones Alice Jones 44 F alice#alicejones.net'
li=st.split()
d[li[0]]=li[1:]
print d
# {'ajones': ['Alice', 'Jones', '44', 'F', 'alice#alicejones.net']}
If you want to change the order of the fields, do so as you are storing them:
d={}
st='ajones Alice Jones 44 F alice#alicejones.net'
li=st.split()
li2=li[1:]
d[li[0]]=[li2[i] for i in (1,0,4,3,2)]
print d
# {'ajones': ['Jones', 'Alice', 'alice#alicejones.net', 'F', '44']}
Or, just use named tuples or a dictionary rather than a list for the data fields.
One you have that part right, you can use it with your file:
# untested...
def create_dict(file_name):
newdict = {}
with open(file_name) as fin:
for line in fin:
li=line.split()
li2=li[1:]
li2[2]=int(li[2])
newdict[li[0]]=[li2[i] for i in (1,0,4,3,2)]
return newdict
So what I'm trying to do is make a dictionary of people and their information but I want to use their names as the main key and have each part of their information to also have a key. I have not been able to figure out how to go about changing the values of their individual information.
I'm not even sure if I'm going about this the right way here is the code.
name = raw_input("name")
age = raw_input("age")
address = raw_input("address")
ramrod = {}
ramrod[name] = {'age': age}, {'address' : address}
print ramrod
#prints out something like this: {'Todd': ({'age': '67'}, {'address': '55555 FooBar rd'})}
What you are looking for is a simple nested dictionary:
>>> data = {"Bob": {"Age": 20, "Hobby": "Surfing"}}
>>> data["Bob"]["Age"]
20
A dictionary is not a pair - you can store more than one item in a dictionary. So you want one dictionary containing a mapping from name to information, where information is a dictionary containing mappings from the name of the information you want to store about the person to that information.
Note that if you have behaviour associated with the data, or you end up with a lot of large dictionaries, a class might be more suitable:
class Person:
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby
>>> data = {"Bob": Person("Bob", 20, "Surfing")}
>>> data["Bob"].age
20
You were close
ramrod[name] = {'age': age, 'address' : address}