In my Ruby application I have a hash table:
c = {:sample => 1,:another => 2}
I can handle the table like this:
[c[:sample].nil? , c[:another].nil? ,c[:not_in_list].nil?]
I'm trying to do the same thing in Python. I created a new dictionary:
c = {"sample":1, "another":2}
I couldn't handle the nil value exception for:
c["not-in-dictionary"]
I tried this:
c[:not_in_dictionery] is not None
and it is returning an exception instead of False. How do I handle this?
In your particular case, you should probably do this instead of comparing with None:
"not_in_dictionary" in c
If you were literally using this code, it will not work:
c[:not_in_dictionary] is not None
Python doesn't have special :keywords for dictionary keys; ordinary strings are used instead.
The ordinary behaviour in Python is to raise an exception when you request a missing key, and let you handle the exception.
d = {"a": 2, "c": 3}
try:
print d["b"]
except KeyError:
print "There is no b in our dict!"
If you want to get None if a value is missing you can use the dict's .get method to return a value (None by default) if the key is missing.
print d.get("a") # prints 2
print d.get("b") # prints None
print d.get("b", 0) # prints 0
To just check if a key has a value in a dict, use the in or not in keywords.
print "a" in d # True
print "b" in d # False
print "c" not in d # False
print "d" not in d # True
Python includes a module that allows you to define dictionaries that return a default value instead of an error when used normally: collections.defaultdict. You could use it like this:
import collections
d = collections.defaultdict(lambda: None)
print "b" in d # False
print d["b"] # None
print d["b"] == None # True
print "b" in d # True
Notice the confusing behaviour with in. When you look up a key for the first time, it adds it pointing to the default value, so it's now considered to be in the dict.
Related
How can I detect some missing key on location.raw["address"] dictionary. This because, some address doesn't have ['city'] or ['road'] key :(
It gives difficult to me to save the data in the dataframe Python.
This is my code:
from geopy.geocoders import Nominatim
r=[]
h=[] #empty list
c=[]
for i in df['coordinates']:
loc=geolocator.reverse("%s"%i,timeout=120)
print(loc)
if loc.raw["address"]["road"] == None: #i tried use this way, not works
r.append(" ")
print("masuk 1")
else:
road=loc.raw["address"]["road"]
r.append(road)
print("masuk 2")
ham=loc.raw["address"]
name=loc.raw["display_name"]
h.append(ham)
c.append(name)
df = pd.DataFrame({'text':text,'city':c,'neighbourhood':h})
You could use in keyword to check if key presented in dict:
a = {1:2, 'x': [3,4]}
print(1 in a) # True
print(2 in a) # False
print('x' in a) # True
Also, dict objects has get method, which returns some value if key is absent:
a.get(1) # 2
a.get(2) # None -- default value
a.get(2, 'n/a') # 'n/a'
I'm using a dictionary to count how many times different items appear in a dataset. In the init of the class, I create the property as a dictionary like this
self.number_found = {}
The first time I find any particular item, I would get a KeyError if I try to do this because the item isn't in the dictionary yet
self.number_found[item] = 1
so I ended up creating a function that checks if an entry is already in the dictionary and if not, adds it for the first time
def _count_occurrences(self, item):
try:
#this checks to see if the item's already in the dict
self.number_found[item] = self.number_found[item] + 1
x = self.number_found[item]
except KeyError:
x = 1
#this adds an item if not in the dict
self.number_found[item] = x
return x
However, this is not working as intended if I find a second occurrence of an item in a dataset.
Let's say there are two 'elephant' in my dataset. When I print self.number_found to the console this is what I get
{'elephant': 1}
{'elephant': None}
and I get this error when adding the second occurrence
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
Question: what's the right way to check if the key's already in the dictionary (with an explanation as to why the 1 is changing to a None)
You can use a defaultdict:
from collections import defaultdict
self.number_found = defaultdict(int)
The first time an item is accessed, its value will take a default of 0
A None is returned because you're not returning anything in your try branch
The return at the end of the except block must be moved out. That way, x is returned for both cases
class C(object):
def __init__(self):
self.number_found = {}
def _count_occurrences(self, item):
try:
#this checks to see if the item's already in the dict
self.number_found[item] = self.number_found[item] + 1
x = self.number_found[item]
except KeyError:
x = 1
#this adds an item if not in the dict
self.number_found[item] = x
return x
c = C()
r = c._count_occurrences('elephant')
print r
print c.number_found
r = c._count_occurrences('elephant')
print r
print c.number_found
Here is a test run first with outdented return, then with it where you have it in your OP:
jcg#jcg:~/code/python/stack_overflow$ python number_found.py
1
{'elephant': 1}
2
{'elephant': 2}
jcg#jcg:~/code/python/stack_overflow$ python number_found.py
1
{'elephant': 1}
None
{'elephant': 2}
As you can see, the second version returns None since there is no return from the _count_occurrences try block
Suppose you have something such as
a = b
but perhaps b does not exist.
can the value for a automatically be declared as "0" or.. perhaps "None" or something ?
You can use a try and except clause to catch the NameError of b not existing. See Handling Exceptions in the Python docs.
try:
a = b
except NameError:
a = None
Depending on where b comes from, you could do
a = locals().get('b', 0)
or
a = globals().get('b', 0)
Try this,
a =vars().get('b', None)
Solution 1
Note you can use static code checker that will find this bug. Examples:
http://www.pylint.org/ (docs : http://docs.pylint.org/tutorial.html)
Eclipse PyDev
Solution 2
You can have null-coalescing operator in python with:
a = b if b is not None else "default value"
If your lazy then this can be simplified to
a = b or "some default value"
Example
42 or "something" # returns 42
0 or "something" # returns "something"
None or "something" # returns "something"
False or "something" # returns "something"
"" or "something" # returns "something"
Alternative way would be to check if variable exists in context:
if 'b' in locals():
# local variable b exists.
if 'b' in globals():
# local variable b exists.
For example this will result something like:
a = if 'b' in locals() b else 0
a = if 'b' in globals() b else 0
try this: Calling b, and if there's an error (if b not exist), then b=0.
try:
b
except:
b = 0
a = b
I am trying to check if a dictionary is empty but it doesn't behave properly. It just skips it and displays ONLINE without anything aside from the display the message. Any ideas why ?
def isEmpty(self, dictionary):
for element in dictionary:
if element:
return True
return False
def onMessage(self, socket, message):
if self.isEmpty(self.users) == False:
socket.send("Nobody is online, please use REGISTER command" \
" in order to register into the server")
else:
socket.send("ONLINE " + ' ' .join(self.users.keys()))
Empty dictionaries evaluate to False in Python:
>>> dct = {}
>>> bool(dct)
False
>>> not dct
True
>>>
Thus, your isEmpty function is unnecessary. All you need to do is:
def onMessage(self, socket, message):
if not self.users:
socket.send("Nobody is online, please use REGISTER command" \
" in order to register into the server")
else:
socket.send("ONLINE " + ' ' .join(self.users.keys()))
Here are three ways you can check if dict is empty. I prefer using the first way only though. The other two ways are way too wordy.
test_dict = {}
if not test_dict:
print "Dict is Empty"
if not bool(test_dict):
print "Dict is Empty"
if len(test_dict) == 0:
print "Dict is Empty"
d = {}
print(len(d.keys()))
If the length is zero, it means that the dict is empty.
Simple ways to check an empty dict are below:
a = {}
if a == {}:
print ('empty dict')
if not a:
print ('empty dict')
Method 1 is more strict, because when a = None, method 1 will provide the correct result, but method 2 will give an incorrect result.
A dictionary can be automatically cast to boolean which evaluates to False for empty dictionary and True for non-empty dictionary.
if myDictionary: non_empty_clause()
else: empty_clause()
If this looks too idiomatic, you can also test len(myDictionary) for zero, or set(myDictionary.keys()) for an empty set, or simply test for equality with {}.
The isEmpty function is not only unnecessary but also your implementation has multiple issues that I can spot prima-facie.
The return False statement is indented one level too deep. It should be outside the for loop and at the same level as the for statement. As a result, your code will process only one, arbitrarily selected key, if a key exists. If a key does not exist, the function will return None, which will be cast to boolean False. Ouch! All the empty dictionaries will be classified as false-nagatives.
If the dictionary is not empty, then the code will process only one key and return its value cast to boolean. You cannot even assume that the same key is evaluated each time you call it. So there will be false positives.
Let us say you correct the indentation of the return False statement and bring it outside the for loop. Then what you get is the boolean OR of all the keys, or False if the dictionary empty. Still you will have false positives and false negatives. Do the correction and test against the following dictionary for an evidence.
myDictionary={0:'zero', '':'Empty string', None:'None value', False:'Boolean False value', ():'Empty tuple'}
1st Way
len(given_dic_obj)
It returns 0 if there are no elements.
Else, returns the size of the dictionary.
2nd Way
bool(given_dic_object)
Returns False if the dictionary is empty, else return True.
You can also use get(). Initially I believed it to only check if key existed.
>>> d = { 'a':1, 'b':2, 'c':{}}
>>> bool(d.get('c'))
False
>>> d['c']['e']=1
>>> bool(d.get('c'))
True
What I like with get is that it does not trigger an exception, so it makes it easy to traverse large structures.
use 'any'
dict = {}
if any(dict) :
# true
# dictionary is not empty
else :
# false
# dictionary is empty
Is it possible to check none value in dict
dict = {'a':'None','b':'12345','c':'None'}
My code
for k,v in d.items():
if d[k] != None:
print "good"
else:
print "Bad
Prints three good after executing above code snippet.
good
good
good
Required:If value is None than not printing good for dict key a and c.
Your none values are actually strings in your dictionary.
You can check for 'None'
or use actual python None value.
d = {'a':None,'b':'12345','c':None}
for k,v in d.items():
if d[k] is None:
print "good"
else:
print "Bad"
prints "good" 2 times
Or if you Have to use your current dictionary just change your check to look for 'None'
additionally dict is a python built in type so it is a good idea not to name variables dict
Define your dictionary with
d = {'a': None}
rather than
d = {'a': 'None'}
In the latter case, 'None' is just a string, not Python's None type. Also, test for None with the identity operator is:
for key, value in d.iteritems():
if value is None:
print "None found!"
def none_in_dict(d):
for _, value in d.items():
if value is None:
return True
return False
And the use is:
if none_in_dict(my_dict):
logger.error(my_err_msg)
Instead of using "if value is None" you can simply use
d = {'a':None, 'b':'12345', 'c':None, 'd':'None'}
for k, v in d.items():
if v:
print("good")
else:
print("bad")
"if v" will be True if there is any kind of value except None. Hence you don't have to explicitly use None keyword in if condition (if v is None).
Result:
bad
good
bad
good
In last case the value for key 'd' is 'None' - as a string not python value None