searching "key" in a dictionary - python

Below you will see a snippet of a code where I created a dictionary in which words from a product review are stored. Now, I am writing a function that will return the number of occurrences of the word present in the dictionary. If it isn't present, it returns 0.
(This function will be used later for another purpose. As one of the member pointed, I could use dict.get() to extract the key. however, when I tried that, I got an attribute error:'SArray' object has no attribute 'get')
Can anyone point out any obvious mistake I might have made?
Thanks in advance.
Edit:
Here is the code:
word_list=turicreate.text_analytics.count_words(products['review'])
def selected_w_count(key):
if key in word_list:
return word_list[key]
else:
return 0
selected_w_count('wise')
output ->> 0
Snapshot of the code

You have a typo in selected_w_count(key) function, if key in world_list: should be if key in word_list:.
Based on your comment that the type of word_list is an array, you may want to use word_list[0].get('wise', 0) in place of the function call. This will get the dict from the array and get key 'wise' with a default value of 0.

It seems that your code returns a turicreate.SArray object but not a standard dict object, so the get function don't work.
I search for the document and find it at:
https://apple.github.io/turicreate/docs/api/generated/turicreate.SArray.html
And maybe you can use the function turicreate.SArray.dict_trim_by_keys() to filter by the given keys and use turicreate.SArray.dict_values() to get the value, just like this:
def selected_w_count(key_word):
word_list.dict_trim_by_keys([key_word], exclude=False).dict_values() if word_list.dict_trim_by_keys([key_word], exclude=False) else 0
You can also just provide a list of key words, just change it like this:
def selected_w_count(keywords_list):
word_list.dict_trim_by_keys(keywords_list, exclude=False).dict_values() if word_list.dict_trim_by_keys(keywords_list, exclude=False) else 0
The documents of these functions are here:
https://apple.github.io/turicreate/docs/api/generated/turicreate.SArray.dict_trim_by_keys.html
https://apple.github.io/turicreate/docs/api/generated/turicreate.SArray.dict_values.html
Take care that the true result will also return A SArray of list type but not just a num.
Not sure whether it works, hope it can help you.

Related

For-loop/if -statement with character range

I'm creating a for loop with an if statement to append a value to a new variable if a specific condition is met. I did the same thing earlier, without the character range of i, and it worked fine. When I try the code below, it doesn't work and shoots out 'KeyError: 0', which doesn't make sense because merge_image1 is a list and not a dictionary.
Hope someone is able to help out!
behav_op1 and merge_image1 are both lists, where each element is a image file pathway (string).
This is the code that is doing the same thing, minus the character range, but for a different variable and works fine:
for i in behav_op1:
if i == 'Stimuli/Operations (Post-study)/main.png':
behav_opIdentity1.append('maintain')
elif i == 'Stimuli/Operations (Post-study)/supp.png':
behav_opIdentity1.append('suppress')
This is the code causing the issue:
for i in merge_image1:
if i[0:36] == 'Stimuli/Faces/resized_positive_faces':
image_valence1.append('positive')
elif i[0:31] == 'Sitmuli/Faces/resized_neg_faces':
image_valence.append('negative')
If I had to guess, KeyError: 0 is raised in line
if i[0:36] == 'Stimuli/Faces/resized_positive_faces':
where you're giving 0 as a key for i. if i were a String, this should probably work. However, it looks like the elements of merge_image1 aren't just Strings, but they are accessed through a key. A key generally needs to be a String itself instead of an int like 0.
The solution is to double check the type of i and access it according to its type. For instance, if i is a dict (a classical example of a container accessed by a key) consisting of a single pair, you'll need to do something like
if list(i.keys())[0][0:36] == 'Stimuli/Faces/resized_positive_faces':
or (better) use startswith suggested in the comments,
if list(i.keys())[0].startswith('Stimuli/Faces/resized_positive_faces'):
BTW if you want to check the type of i, just do
print(merge_image1[0])
If this fails because of indexing issues, then the whole code should be probably be rewritten to work with whatever merge_image1 type is.

Dictionary that doesn't exist returning name of string, how to skip this Python

I have a dictionary that holds different value and id's.
The first index in the dictionary does not hold the 'id' dictionary, but the second index does
The problem I am having is when I print:
return[0]['values']['id']
It returns
'id'
Because there is no such dictionary in the first index
The second index
return[1]['values']['id']
The 'id' dictionary does exist so returns
[{"id": "4651234", "type":"instant"}]
I'm trying to create a list of only the id values that exist, how do I get it to skip the all the indexes where the 'id' dictionary does not exist? Rather than stop the program and print the string 'id'.
You can just loop and use a if statement to check if the id exists or not :
id_list = []
for key in return:
if return[key]['values']['id'] != 'id':
id_list.append(return[key]['values']['id'])
(Btw you should avoid naming your variables with name like return or any other keyword that can have a signification for the language)
you can if the returned value it is a list or a string
if isinstance(return[0]['values']['id'],list):
#process the data
elif isinstance(return[0]['values']['id'],str):
#do nothing
Having said that, a couple of recommendations: I assume that you wrote it as an example but, just in case, is not possible to have "return" as the name of the variable since it is a reserved word.
Another point is that if the same call returns different things (i.e. the first returns a str, the second a list with a dictionary in it, etc), it may be an indication that the data needs some cleaning before trying to access it. Otherwise you may end up with nasty results and you won't know where they are coming from.

How to get result from a dictionary with lists as the values

I have a JSON file with n number of dictionaries as listed below in the snippet. I am trying to fetch the value against the key but it fails in my code when the value is defined as a list like in the below example for key affected_packages. I tried to check why my code fails, so it looks like it pulls no data out of it this fails. I just see two brackets [] as output instead of "thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"
{"bugzilla_description":"CVE-2021-23992 Mozilla: A crafted OpenPGP key with an invalid user ID could be used to confuse the user","cvss_score":null,"cvss_scoring_vector":null,"CWE":"CWE-347","affected_packages":["thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"],"resource_url":"https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-23992.json","cvss3_scoring_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L","cvss3_score":"4.3"}
I am doing like below in my code as I need to prepare a worksheet. Sample snippet:
for i in range(offs):
ws.cell(row=r+1+i,column=2).value = v['current'][i]
if 'affected_packages' in list(tmp1.keys()):
ws.cell(row=r+1+index1,column=11).value = tmp1['affected_packages']
print("affected_packages done")
if 'advisories' in list(tmp1.keys()):
ws.cell(row=r+1+index2,column=13).value = tmp1['advisories']
print("advisories done")
Is there a way I can pull the value correctly for those defined as a list in the dictionary? I need a way so that it won't hamper my existing logic to pull value for normal key: value since while looking up into my JSON file.
So need something which can fulfil both whether my value in the dictionary is as a list or not as a list and I can get value against the keys in my json file.
As mentioned in the other answers, you can test the type of a variable using
if type(some_variable) == list:
# do what you need to do
You do mention that your code breaks, and I guess it's because inserting into a cell expects a String, not the list you pass in the line
ws.cell(row=r+1+index1,column=11).value = tmp1['affected_packages']
So how do we get a string out of a list of strings? It's pretty easy using the join method.
my_list = ["thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"]
as_one_string = ", ".join(my_list)
print(as_one_string)
# Prints out 'thunderbird-0:78.9.1-1.el8_1, thunderbird-0:78.9.1-1.el8_2, thunderbird-0:78.9.1-1.el8_3, thunderbird-0:78.9.1-1.el7_9'
So combining the two ideas:
if 'affected_packages' in list(tmp1.keys()):
ws.cell(row=r+1+index1,column=11).value = tmp1['affected_packages'] if type(tmp1['affected_packages']) != list else ", ".join(tmp1['affected_packages'])
print("affected_packages done")
Quick feedback because I can't comment yet: Please always include an error message and/or the output you get when running your code when you ask a question
If I understand it correctly, you just need to determine if a value in dict is list. You can do that as below:
for i in d.items(): # gets key, value as a tuple.
if isinstance(i[1],list):
print('its a list, process it accordingly')
else:
print('Not a list')
Regarding your second problem, when you don't know if it is a list or something else, you can just check the type, maybe like this:
if type(tmp1['affected_packages']) == list:
# process the list
else:
# process other types
Since you don't know the data type, having this explicit type check seems necessary.

passing fields of an array of collections through functions in python

is there a way of passing a field of an array of collections into a function so that it can still be used to access a element in the collection in python?. i am attempting to search through an array of collections to locate a particular item by comparing it with an identifier. this identifier and field being compared will change as the function is called in different stages of the program. is there a way of passing up the field to the function, to access the required element for comparison?
this is the code that i have tried thus far:
code ...
In your code, M_work is a list. Lists are accessed using an index and this syntax: myList[index]. So that would translate to M_work[place] in your case. Then you say that M_work stores objects which have fields, and you want to access one of these fields by name. To do that, use getattr like this: getattr(M_work[place], field). You can compare the return value to identifier.
Other mistakes in the code you show:
place is misspelled pace at one point.
True is misspelled true at one point.
The body of your loop always returns at the first iteration: there is a return in both the if found == True and else branches. I don't think this is what you want.
You could improve your code by:
noticing that if found == True is equivalent to if found.
finding how you don't actually need the found variable.
looking at Python's for...in loop.

Python - If value in dictionary then

Here's my code
if "value" not in dictionary():
do something
else:
do something else
I get the error 'TypeError: 'dict' object is not callable.
I've tried changing the first line to
if dictionary["value"]:
But get a different error. Where am I going wrong here?
Assuming dictionary is in fact a dict() composed of key-values then it would be
if 'value' not in dictionary:
...etc
The error is essentially telling you that you are erroneously attempting to call a non-callable object as if it were a method/function.
If you are not particularly interested in whether or not a value exists you may use a method I am personally a fan of:
some_value = dictionary.get('value', 'valueIfNotPresent')
do_something(some_value)
The above allows you to provide a sentinel value (which is provided when the key does not exist). This can help with branch elimination (e.g. not having to if/else it, just allowing your code to act upon the sentinel) or at least reduce logic in checking for the existence of a key (unless the absence of a key is important).
Both are quite readable however and your mileage may vary.
EDIT:
#user1857805 is correct, if you are attempting to find out if a value is in a dictionary then the above (while still good and valid to know) is not enough. You will need to get the .values() as a list from the dictionary; however, as a dictionary may contain dictionaries you will need to recurse the dictionary to find all of the possibly stored values.
try using the following:
if 'value' not in dictionary.values():
do something
else:
do something else.

Categories

Resources