Read json key value as insensitive key - python

I need to be able to pull the value of the key 'irr' from this json address in python:
IRR = conparameters['components'][i]['envelope'][j]['irr']
Even if 'irr' is any oher case, like IRR, Irr... etc.
Is that easy?

There's nothing built-in that does it, you have to search for a matching key.
See Get the first item from an iterable that matches a condition for how to write a first() function that finds the first element of an iterable that matches a condition. I'll use that in the solution below.
cur = conparameters['components'][i]['envelope'][j]
key = first(cur.keys(), lambda k: lower(k) == 'irr')
IRR = cur[key]

Related

Using next instead of break in comprehension list

Considering a word, I'd like to search it in a dictionary, first as key and then as value.
I implemented in the following way:
substitution_dict={'land':['build','construct','land'],
'develop':['develop', 'builder','land']}
word='land'
key = ''.join([next(key for key, value in substitution_dict.items() if word == key or word in value)])
The idea is to take advantage of short-circuiting, the word is first compare with the key, else with the value. However, I'd like to stop when is found in the key.
Running the above snippet works good. However, when the word changes to other word not present in the dictionary, it throws StopIteration error due to the next statement which is not finding results.
I was wondering if this is doable in one line as I intended.
Thanks
You could pass a default argument in next().And next() would only return only one element,so "".join([]) is unnecessary.
Code below:
key = next((key for key, value in substitution_dict.items() if word == key or word in value), None)
When the iterator is exhausted, it would return None.
Or if you really want to use it with ''.join, like:
key = "".join([next((key for key, value in substitution_dict.items() if word == key or word in value), "")])

How to get the key element based on matching the key element in a dictionary?

I have a dictionary which looks like this:
dictionary={
"ABC-6m-RF-200605-1352": "s3://blabla1.com",
"ABC-3m-RF-200605-1352": "s3://blabla2.com",
"DEF-6m-RF-200605-1352": "s3://blabla3.com"
}
Now, I want to do a matching which takes input such as helper="ABC-6m" and tries to match this string to the key of the dictionary and returns the key (not the value)!
My code currently looks like this but it is not robust, i.e. sometimes it works and sometimes it does not:
dictionary_scan = dict((el, el[:7]) for el in dictionary)
#swapping key and value
dictionary_scan = dict((v, k) for k, v in dictionary.items())
#concat string components in helper variable
helper = 'ABC'+'-'+'6m'
out=list(value for key, value in dictionary_scan.items() if helper in key)
The expected output is: 'ABC-6m-RF-200605-1352'. Sometimes this works in my code but sometimes it does not. Is there a better and more robust way to do this?
If you make a dictionary that maps prefixes to full keys, you'll only be able to get one key with a given prefix.
If there can be multiple keys that start with helper, you need to check them all with an ordinary list comprehension.
out = [key for key in dictionary if key.startswith(helper)]

Sorting a list of dict from redis in python

in my current project i generate a list of data, each entry is from a key in redis in a special DB where only one type of key exist.
r = redis.StrictRedis(host=settings.REDIS_AD, port=settings.REDIS_PORT, db='14')
item_list = []
keys = r.keys('*')
for key in keys:
item = r.hgetall(key)
item_list.append(item)
newlist = sorted(item_list, key=operator.itemgetter('Id'))
The code above let me retrieve the data, create a list of dict each containing the information of an entry, problem is i would like to be able to sort them by ID, so they come out in order when displayed on my html tab in the template, but the sorted function doesn't seem to work since the table isn't sorted.
Any idea why the sorted line doesn't work ? i suppose i'm missing something to make it work but i can't find what.
EDIT :
Thanks to the answer in the comments,the problem was that my 'Id' come out of redis as a string and needed to be casted as int to be sorted
key=lambda d: int(d['Id'])
All values returned from redis are apparently strings and strings do not sort numerically ("10" < "2" == True).
Therefore you need to cast it to a numerical value, probably to int (since they seem to be IDs):
newlist = sorted(item_list, key=lambda d: int(d['Id']))

Python Lambda Comparing Dictionaries

I have some code here to compare two dictionaries using Lambda and filter. Basically I have a required Tags dictionary and a Tags Dictionary for each EC2 Instance.
I need to be able to process two conditions. The first condition is only check whether the all the Keys in Required Tags exist in Instance Tags and they are not blank.
requiredTags = {'Name' : ['WebSense','NAT-V2'] }
instanceTags = i['Instances'][0]['Tags']
requiredTagsPresent = filter(lambda x: x['Key'] in requiredTags and
x['Value'] is not '', instanceTags)
The next condition is the most common - check whethere all the keys and their corresponding values are
requiredTagsPresent = filter(lambda x: x['Key'] in requiredTags and x['Value'] in requiredTags, instanceTags)
So far, I haven't been able to accomplish both of the above in a single script.
The last condition is the one I am having trouble with. I want to have a specific tag value that if present, we only check for the existence of the corresponding key regardless of the value. I have no idea how to do something like that.
Any tips?
This kind of thing is much easier to do if you use the built-in function all rather than lambda and filter. To check if all the keys in required_tags exist in instance_tags and they are not blank, use:
all_present = all(k in instance_tags and instance_tags[k] for k in required_tags.keys())
To check whether all the keys and values in instance_tags are in required_tags, use:
all_present2 = all(k in required_tags and v in required_tags for k, v in instance_tags.items())
This assumes Python3.
But I am not sure this is what you want, since your description of the second test condition has words left off at the end: "check whethere [sic] all the keys and their corresponding values are ". Are what? Also, when you told me in your comment what the structure of instance_tags was, you had unmatched square brackets. You said it was a dictionary but it looks like a list of dictionaries, each containing one item.

How to check if keys exists and retrieve value from Dictionary in descending priority

I have a dictionary and I would like to get some values from it based on some keys. For example, I have a dictionary for users with their first name, last name, username, address, age and so on. Let's say, I only want to get one value (name) - either last name or first name or username but in descending priority like shown below:
(1) last name: if key exists, get value and stop checking. If not, move to next key.
(2) first name: if key exists, get value and stop checking. If not, move to next key.
(3) username: if key exists, get value or return null/empty
#my dict looks something like this
myDict = {'age': ['value'], 'address': ['value1, value2'],
'firstName': ['value'], 'lastName': ['']}
#List of keys I want to check in descending priority: lastName > firstName > userName
keySet = ['lastName', 'firstName', 'userName']
What I tried doing is to get all the possible values and put them into a list so I can retrieve the first element in the list. Obviously it didn't work out.
tempList = []
for key in keys:
get_value = myDict.get(key)
tempList .append(get_value)
Is there a better way to do this without using if else block?
One option if the number of keys is small is to use chained gets:
value = myDict.get('lastName', myDict.get('firstName', myDict.get('userName')))
But if you have keySet defined, this might be clearer:
value = None
for key in keySet:
if key in myDict:
value = myDict[key]
break
The chained gets do not short-circuit, so all keys will be checked but only one used. If you have enough possible keys that the extra lookups matter, use the for loop.
Use .get(), which if the key is not found, returns None.
for i in keySet:
temp = myDict.get(i)
if temp is not None:
print temp
break
You can use myDict.has_key(keyname) as well to validate if the key exists.
Edit based on the comments -
This would work only on versions lower than 3.1. has_key has been removed from Python 3.1. You should use the in operator if you are using Python 3.1
If we encapsulate that in a function we could use recursion and state clearly the purpose by naming the function properly (not sure if getAny is actually a good name):
def getAny(dic, keys, default=None):
return (keys or default) and dic.get(keys[0],
getAny( dic, keys[1:], default=default))
or even better, without recursion and more clear:
def getAny(dic, keys, default=None):
for k in keys:
if k in dic:
return dic[k]
return default
Then that could be used in a way similar to the dict.get method, like:
getAny(myDict, keySet)
and even have a default result in case of no keys found at all:
getAny(myDict, keySet, "not found")

Categories

Resources