How to print specific value from specific key from JSON in Python - python

I wrote 2 functions so I can get champion ID knowing champion Name but then I wanted to get champion Name knowing champion ID but I cannot figure it out how to extract the name because of how the data structured.
"data":{"Aatrox":{"version":"8.23.1","id":"Aatrox","key":"266","name":"Aatrox"
so in my code I wrote ['data']['championName'(in this case Aatrox)]['key'] to get the champion ID/key. But how can I reverse it if for example I don't know the champion Name but champions ID. How can I get the champion Name if after writing ['data'] I need to write champion Name so I can go deeper and get all the champions info like ID, title etc..
link: http://ddragon.leagueoflegends.com/cdn/8.23.1/data/en_US/champion.json
Code:
def requestChampionData(championName):
name = championName.lower()
name = name.title()
URL = "http://ddragon.leagueoflegends.com/cdn/8.23.1/data/en_US/champion/" + name + ".json"
response = requests.get(URL)
return response.json()
def championID(championName):
championData = requestChampionData(championName)
championID = str(championData['data'][championName]['key'])
return championID

since python values are passed by reference you can make a new dict with keys as the champion id pointing to the values of the previous dict, that way you dont duplicate too much data. but be carefull if you change data in one dict the data will be changed in the other one too
def new_dict(d):
return { val["id"]:val for val in d.values() }

I solved my problem with this code:
def championNameByID(id):
championData = requestChampionData()
allChampions = championData['data']
for champion in allChampions:
if id == allChampions[champion]['key']:
championName = allChampions[champion]['name']
return championName

Related

BeautifulSoup checking if an element has a specific class

for containerElement in container:
brandingElement = containerElement.find("div", class_="item-branding")
titleElement=containerElement.find("a", class_="item-title")
rating = brandingElement.find("i", {"class":"rating"})["aria-label"]
priceElement = containerElement.find("li", class_="price-current")
so this for loop checks for prices, ratings, and the name of an item on a website. it works. however, some items have no reviews, in which case it fails. how do i fix this? i was thinking of an if statement to check if the containerElement (the actual container the item and all its information is in) has a rating, but im not exacatly sure how to do that
for containerElement in container:
brandingElement = containerElement.find("div", class_="item-branding")
titleElement=containerElement.find("a", class_="item-title")
rating = brandingElement.find("i", {"class":"rating"})["aria-label"] if brandingElement.find("i", {"class":"rating"}) else ""
priceElement = containerElement.find("li", class_="price-current")

Is there any way to change dictonary items comparing with another one?

import json
from urllib import request
infile = request.urlopen('https://restcountries.eu/rest/v1/all')
content_as_python_obj = json.loads(infile.read().decode())
name=[]
boarder=[]
code=[]
for country in content_as_python_obj:
name.append(country['name'])
boarder.append(country['borders'])
code.append(country['alpha3Code'])
countryAndCode=dict(zip(name, code))
countryAndBoarders=dict(zip(name, boarder))
#I would like to replace the codes with the full name to have a dictionary that states the name and the bordering countries with the full name
use the mapping of country code to country name to convert all the country code present in the borders list.
country_code_to_country_name = dict(zip(code, name))
country_borders = dict(zip(name, boarder))
country_borders = {
key: [country_code_to_country_name[v] for v in value]
for key, value in country_borders.items()
}

Building classes from nested dictionaries

So I am new to all this, please pardon my poor formatting and only loose grasp of jargon.
In short, I have a
coins = requests.get("https://bittrex.com/api/v1.1/public/getcurrencies")
that returns json() nested dictionaries (sorry for terrible phrasing) that look like this:
{
"success" : true,
"message" : "",
"result" : [{
"Currency" : "BTC",
"CurrencyLong" : "Bitcoin",
"MinConfirmation" : 2,
"TxFee" : 0.00020000,
"IsActive" : true,
"CoinType" : "BITCOIN",
"BaseAddress" : null
}, {
"Currency" : "LTC",
"CurrencyLong" : "Litecoin",
"MinConfirmation" : 5,
"TxFee" : 0.00200000,
"IsActive" : true,
"CoinType" : "BITCOIN",
"BaseAddress" : null
}]
}
In short I would like to access each dictionary within coins["result"] and build my own values with them to generate a class for each coin so that the inherited code gets filled, like:
class coinbuilder(self, currency, currencyLong, minConfirmation...):
def __init__(self):
self.currency = currency
self.currencyLong = currencyLong
ticker = requests.get("https://bittrex.com/api/v1.1/public/getticker?market=BTC-" + currency)
I understand this code is incorrect, but Im trying to give you an idea of what I am trying to accomplish. Sorry for my terrible phrasing, im new to programming in general and while I have a general grasp of function I am still trying to catch up on jargon.
There are several different ways to do this, you could parse the dictionary inside your __init__ function for example.
I tend to handle this by having a separate #classmethod that is responsible for parsing dictionaries to create instances of my class.
Something like this:
class Coinbuilder:
def __init__(self, cur, curlong):
self.currency = cur
self.currency_long = curlong
#classmethod
def build_from_dict(coin_b, d):
attributes = {'Currency', 'CurrencyLong'}
try:
class_dct = {a: d[a] for a in attributes}
except:
raise ValueError('Input did not contain necessary attributes')
return coin_b(class_dct['Currency'], class_dct['CurrencyLong'])
This way I am not forced to pass Coinbuilder a dictionary to create a class instance, but I have a simple method I can use to parse a dictionary to create an instance of my class.
For this simple example, I can do the following:
x = Coinbuilder.build_from_dict({'Currency': 'BTC', 'CurrencyLong': 'Bitcoin'})
Or I could use:
y = Coinbuilder('BTC', 'Bitcoin')
And get two equal class instances:
print(x.currency, x.currency_long)
print(y.currency, y.currency_long)
Output:
BTC Bitcoin
BTC Bitcoin
Using your sample input as a guide, once you write your #classmethod to parse your dictionary, you could then simply use:
my_coins = []
for result in coins['result']:
my_coins.append(Coinbuilder.build_from_dict(result))
Or:
my_coins = [Coinbuilder.build_from_dict(result) for result in coins['result']]
Here is a total script for what you are trying to do:
import requests
import json
class CoinBuilder:
def __init__(self,dict):
self.currency = dict['Currency']
self.currencyLong = dict['CurrencyLong']
self.minConfirmation = dict['MinConfirmation']
self.txFee = dict['TxFee']
self.isActive = dict['IsActive']
self.coinType = dict['CoinType']
self.baseAddress = dict['BaseAddress']
self.notice = dict['Notice']
coins_response = requests.get("https://bittrex.com/api/v1.1/public/getcurrencies")
all_coins = json.loads(coins_response.content)
list_of_coin_obs = []
for coin in all_coins["result"]:
list_of_coin_obs.append(CoinBuilder(coin))
This script is getting the response, then iterating through the dictionaries in result[] and building CoinBuilder objects from that. All of the created objects are also being stored in a list, list_of_coin_obs[].
You can then print the first 10 results you have, for example, like this:
# Print out the first 10 coins
print("First 10 coins:")
for i in range(1,11):
print(i,") ",list_of_coin_obs[i].currency)
For this example, this would output:
First 10 coins:
1 ) LTC
2 ) DOGE
3 ) VTC
4 ) PPC
5 ) FTC
6 ) RDD
7 ) NXT
8 ) DASH
9 ) POT
10 ) BLK
If you wanted to create a method to look up a specific coin by it's ticker symbol, you could create something like this:
# method to retrieve a specific coin from 'list_of_coin_obs[]'
# we are passing in a parameter, 'coin_abr' to give to our filter
def get_specific_coin_by_abr(coin_abr):
return next(filter(lambda x: x.currency == coin_abr, list_of_coin_obs))
# call our method, which returns a 'CoinBuilder' type
specific_coin = get_specific_coin_by_abr('BTC')
# print our results to show it worked
print('CurrencyName: ',specific_coin.currency,'CurrencyLong: ',specific_coin.currencyLong)
This prints:
CurrencyName: BTC CurrencyLong: Bitcoin
Note: This is assuming that you already have the list_of_coin_obs[] created and in the same scope as this method.
One suggestion, here the class name CoinBuilder doesn't totally make the most sense. A better name for the class/objects would simply be Coin or NamedCurrency or some other similar name. I think I know what you were going for, but this is probably a better fit for your project.
Best of luck.

save two list in one json file

I'm getting data with two lists and I want to save both of them in one single json file can someone help me.
I'm using selenium
def get_name(self):
name = []
name = self.find_elements_by_class_name ('item-desc')
price = []
price = self.find_elements_by_class_name ('item-goodPrice')
for names in name :
names = (names.text)
#print names
for prices in price :
prices = (prices.text)
#print price
I would create a dictionary and then JSON dumps
An example could be:
import json
def get_name(self):
names = [ name.text for name in self.find_elements_by_class_name('item-desc') ]
prices = [ price.text for price in self.find_elements_by_class_name('item-goodPrice')]
with open('output-file-name.json', 'w') as f:
f.write(json.dumps({'names': names, 'prices': prices}))
EDIT: In the first version of the answer I was only creating the JSON, if you want to create a file as well, you should include what suggested by #Andersson comment

How do I look get an associated value in a json variable using python?

How do I look up the 'id' associated with the a person's 'name' when the 2 are in a dictionary?
user = 'PersonA'
id = ? #How do I retrieve the 'id' from the user_stream json variable?
json, stored in a variable named "user_stream"
[
{
'name': 'PersonA',
'id': '135963'
},
{
'name': 'PersonB',
'id': '152265'
},
]
You'll have to decode the JSON structure and loop through all the dictionaries until you find a match:
for person in json.loads(user_stream):
if person['name'] == user:
id = person['id']
break
else:
# The else branch is only ever reached if no match was found
raise ValueError('No such person')
If you need to make multiple lookups, you probably want to transform this structure to a dict to ease lookups:
name_to_id = {p['name']: p['id'] for p in json.loads(user_stream)}
then look up the id directly:
id = name_to_id.get(name) # if name is not found, id will be None
The above example assumes that names are unique, if they are not, use:
from collections import defaultdict
name_to_id = defaultdict(list)
for person in json.loads(user_stream):
name_to_id[person['name']).append(person['id'])
# lookup
ids = name_to_id.get(name, []) # list of ids, defaults to empty
This is as always a trade-off, you trade memory for speed.
Martijn Pieters's solution is correct, but if you intend to make many such look-ups it's better to load the json and iterate over it just once, and not for every look-up.
name_id = {}
for person in json.loads(user_stream):
name = person['name']
id = person['id']
name_id[name] = id
user = 'PersonA'
print name_id[user]
persons = json.loads(...)
results = filter(lambda p:p['name'] == 'avi',persons)
if results:
id = results[0]["id"]
results can be more than 1 of course..

Categories

Resources