So I am working a dictionary with some nice information, and I wan to print out the words in a nicely formatted way by means of another function.
I have this:
norwDict = {
'et hus': {
'pron': 'hUs',
'def': 'house',
'POS': 'noun',
'gen': 'neuter', }
'en blomst' :{
'pron':'blOMst',
'def':'flower',
'POS': 'noun',
'gen':'masc', }
I want to print this so that it looks like:
printWord(norwDict, 'blomst')
en blomst (blOmst), noun
a flower.
What things do I do in order to format it like that in the function def printWord()?
I'd use str.format. See: https://docs.python.org/2/library/string.html#formatstrings
As it is, it would work something like this:
def print_word(your_dict, your_word):
# you need some sort of logic to go from 'blomst' to 'en blomst'
key, = {k for k in your_dict.keys() if your_word in k}
# {'pron': 'blOMSt', ... }
values = your_dict[key]
print """{key} ({pron}), {POS}
a {def}""".format(key=key, **values)
str.format lets you pass in named arguments, which you can easily get here by doing ** unpacking on your inner dict.
Related
payload = {
"data": {
"name": "John",
"surname": "Doe"
}
}
print(payload["data"]["name"])
I want to print out the value of 'name' inside the json. I know the way to do it like above. But is there also a way to print out the value of 'name' with only 1 'search string'?
I'm looking for something like this
print(payload["data:name"])
Output:
John
If you were dealing with nested attributes of an object I would suggest operator.attrgetter, however, the itemgetter in the same module does not seems to support nested key access. It is fairly easy to implement something similar tho:
payload = {
"data": {
"name": "John",
"surname": "Doe",
"address": {
"postcode": "667"
}
}
}
def get_key_path(d, path):
# Remember latest object
obj = d
# For each key in the given list of keys
for key in path:
# Look up that key in the last object
if key not in obj:
raise KeyError(f"Object {obj} has no key {key}")
# now we know the key exists, replace
# last object with obj[key] to move to
# the next level
obj = obj[key]
return obj
print(get_key_path(payload, ["data"]))
print(get_key_path(payload, ["data", "name"]))
print(get_key_path(payload, ["data", "address", "postcode"]))
Output:
$ python3 ~/tmp/so.py
{'name': 'John', 'surname': 'Doe', 'address': {'postcode': '667'}}
John
667
You can always later decide on a separator character and use a single string instead of path, however, you need to make sure this character does not appear in a valid key. For example, using |, the only change you need to do in get_key_path is:
def get_key_path(d, path):
obj = d
for key in path.split("|"): # Here
...
There isn't really a way you can do this by using the 'search string'. You can use the get() method, but like getting it using the square brackets, you will have to first parse the dictionary inside the data key.
You could try creating your own function that uses something like:
str.split(sep=None, maxsplit=-1)
Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made).
def get_leaf_value(d, search_string):
if ":" not in search_string:
return d[search_string]
next_d, next_search_string = search_string.split(':', 1)
return get_value(d[next_d], next_search_string)
payload = {
"data": {
"name": "John",
"surname": "Doe"
}
}
print(payload["data"]["name"])
print(get_leaf_value(payload, "data:name"))
Output:
John
John
This approach will only work if your data is completely nested dictionaries like in your example (i.e., no lists in non-leaf nodes) and : is not part of any keys obviously.
Here is an alternative. Maybe an overkill, it depends.
jq uses a single "search string" - an expression called 'jq program' by the author - to extract and transform data. It is a powerful tool meaning the jq program can be quite complex. Reading a good tutorial is almost a must.
import pyjq
payload = ... as posted in the question ...
expr = '.data.name'
name = pyjq.one(expr, payload) # "John"
The original project (written in C) is located here. The python jq libraries are build on top of that C code.
I'm a newbie in Python trying to turn information from an Excel file into JSON output.
I'm trying to parse this Python list:
value = ['Position: Backstab, Gouge,', 'SumPosition: DoubleParse, Pineapple']
into this JSON format:
"value": [
{
"Position": [
"Backstab, Gouge,"
]
},
{
"SumPosition": [
"DoubleParse, Pineapple"
]
}
]
Please note:
This list was previously a string:
value = 'Position: Backstab, Gouge, SumPosition: DoubleParse, Pineapple'
Which I turned into a list by using re.split().
I've already turned the string into a list by using re.split, but I still can't turn the inside of the string into a dict, and the value from the dict into a list.
Is that even possible? Is it the case to format the list/string with JSON or previously prepare the string itself so it can receive the json.dump method?
Thanks in advance!
You can iterate over the list to achieve desired result.
d = {'value': []}
for val in value:
k, v = val.split(':')
tmp = {k.strip() : [v.strip()]}
d['value'].append(tmp)
print(d)
{'value': [{'Position': ['Backstab, Gouge,']},
{'SumPosition': ['DoubleParse, Pineapple']}]}
Here is a quick way.
value = ['Position: Backstab, Gouge,',
'SumPosition: DoubleParse, Pineapple']
dictionary_result = {}
for line in value:
key, vals = line.split(':')
vals = vals.split(',')
dictionary_result[key] = vals
Remaining tasks for you: trim off empty strings from result lists like [' Backstab', ' Gouge', ''], and actually convert the data from a Python dict to a JSON file
I cannot get values inside my python dictionairy, created from a json file, to print at all. Here is my JSON:
{
"Questions": [
{
"Q1":"What is capital of egypt?",
"T":"London",
"2":"France",
"3":"Egypt"
},
{
"Q2":"What is capital of USA?",
"T":"London",
"2":"France",
"3":"Egypt"
}
]
}
And here is my python:
import json
with open("questions.json") as f:
data = json.load(f)
print(data["Questions"]["Q1"])
This returns the error: list indices must be integers or slices, not str
What am I doing wrong? I have checked the syntax for printing and it all seems correct.
A good strategy is to start by removing code until it works. For example, instead of
print(data["Questions"]["Q1"])`
You should try
print(data["Questions"])`
The output from this is
[{'Q1': 'What is capital of egypt?', 'T': 'London', '2': 'France', '3': 'Egypt'},
{'Q2': 'What is capital of USA?', 'T': 'London', '2': 'France', '3': 'Egypt'}]
From there, you can try to index like you were doing in the question:
[{'Q1': 'What is capital of egypt?', 'T': 'London', '2': 'France', '3': 'Egypt'},
{'Q2': 'What is capital of USA?', 'T': 'London', '2': 'France', '3': 'Egypt'}]['Q1']
Except that doesn't make sense, because you're trying to index a list, and indexes in a list are ints, not strings.
So to get the result you're expecting, you should use data["Questions"][0] to index the first question.
A better solution, in my opinion, is to change the structure of the JSON to something that makes a little more sense. This is how I would do it:
{
"Questions": {
"Q1": {
"Q":"What is capital of egypt?",
"T":"London",
"2":"France",
"3":"Egypt"
},
"Q2" : {
"Q":"What is capital of USA?",
"T":"London",
"2":"France",
"3":"Egypt"
}
}
}
Now you can perform a lookup with Q1 or Q2 just like you expect.
The value of Questions is a list. Like the error says, the index must be an integer.
The first question is going to be data["Questions"][0], the second is data["Questions"][1] and so on.
If you want the value of "Q1" for the first question, you need to use data["Questions"][0]["Q1"]
Try this piece of code:
import json
with open("questions.json") as f:
data = json.load(f)
print(data["Questions"][0]["Q1"], data["Questions"][1]["Q1"])
Output is
"Passanger status:\n passanger cfg086d96 is unknown\n\n"
i want to convert this into json object like
{
"Passanger_status": "passanger cfg086d96 is unknown"
}
just apply json.dumps() to this native python dictionary composed in one-line:
{k.replace(" ","_"):v.strip() for k,v in (x.split(":") for x in ["Passanger status:\n passanger cfg086d96 is unknown\n\n"])}
the inner generator comprehension avoids to call split for each part of the dict key/value. The value is stripped to remove trailing/leading blank spaces. The space characters in the key are replaced by underscores.
result is (as dict):
{'Passanger status': 'passanger cfg086d96 is unknown'}
as json string using indent to generate newlines:
>>> print(json.dumps({k.replace(" ","_"):v.strip() for k,v in (x.split(":") for x in ["Passanger status:\n passanger cfg086d96 is unknown\n\n"])},indent=2))
{
"Passanger_status": "passanger cfg086d96 is unknown"
}
You can try this one also
data_dic = dict()
data = "Passanger status:\n passanger cfg086d96 is unknown\n\n"
x1 , x2 = map(str,data.split(":"))
data_dic[x1] = x2
print data_dic
If you find it simple
Output :
{'Passanger status': '\n passanger cfg086d96 is unknown\n\n'}
and for space to underscore you can use replace method in keys of the dictionary.
As title ,I web crawler the diigo , and have many list, I become the list to the set().Like this:
data = [ ['spanish', 'web2.0', 'e-learning', 'education', 'social', 'spain', 'tools', 'learning', 'google', 'e-learning2.0'], ['education', 'technology', 'learning', 'classroom', 'students', 'web2.0'], ['education'], ['technology'] ]
And doing something calculate
search_table = {}
for i, tag_list in enumerate(data):
for tag in tag_list:
if tag not in search_table:
search_table[tag] = set()
search_table[tag].add(i)
# How many people have `technology`?
print(len(search_table["technology"]))
# How many people have `education`?
print(len(search_table["education"]))
# How many people have both `technology`, `education`?
print(len(search_table["technology"] & search_table["education"]))
data have many tags, i want to do this ->print(len(search_table["technology"]))<- technology can auto change next world like classroom.
i realy don't konw how to do,i only think is
for u in user_data:
print u
but how to add the world to print(len(search_table[" u "]))
sincerely bob
I think I understand what you mean. You were nearly there:
user_data = ["technology", "classroom"]
for u in user_data:
print(len(search_table[u]))
will first print the number of items in search_table["technology"] and then print the number of items in search_table["classroom"].
When you're working with lists, you access elements of the list using numbers so you will not need to change the word 'code'. You would merely access it like this:
>>> user_data = ['code','java','learn']
>>> user_data[0]
'code'
>>>
Generally, when you're accessing elements like user_data["code"], it's because you're accessing keys of a dictionary like so:
>>> user_data = {'code':'java, python, ruby'}
>>> user_data['code']
'java, python, ruby'
Depending on how you store the information will affect how you're accessing that stored information. Considering you have user data, you will probably want to store them in dictionaries in lists like:
[
{'name': 'bob', 'code': 'java, python', 'school':'StackOU'},
{'name': 'bobina', ...
]
You'd access bob's coding skills like:
>>> user_data = [
... {'name': 'bob', 'code': 'java, python', 'school':'StackOU'},
... ]
>>> user_data[0]['code']
'java, python'