Geopy not have all same key for address - python

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'

Related

opening dictionaries in bool data type

we could open a dictionary with **:
dict = {"v_1":"a","v_2":"b"}
function(**dict) >
function(v_1 = "a",v_2 = "b")
So is it possible to open dictionaries to represent bool expressions so:
dict = {"v_1":"a","v_2":"b"}
function(???) >
function(v_1 == "a",v_2 == "b")
where i want to use this process:
https://docs.sqlalchemy.org/en/14/core/tutorial.html#inserts-updates-and-deletes
in this code as an example:
tmt = users.update().where(users.c.name == 'jack').values(name='ed')
on where function .where(users.c.name == 'jack').
I also have a dictionary:
{"name":"jack"}
Is there any way I can pass this dictionary to the function as desired?
Check **kwargs structure. You can see an example below.
def function(*args,**kwargs):
for i in args:
print(i)
for k,v in kwargs.items():
print('key: ',k,'value: ',v)
function(1,2,3,'args' , val = 'kwargs')
output
#1
#2
#3
#args
#key: val value: kwargs
What I did not understand when asking the question is that the operator == is not a bool value! was used as an object constructor. so v_1 == "a" was creating an object with v1. I've done this by scrolling through a list for now. Although it's not exactly the answer I wanted, my solution is:
dict = {"v_1":"a","v_2":"b"}
list = []
for i in dict:
list.append(i == dict[i])
function(*l)

Return next key of a given dictionary key, python 3.6+

I am trying to find a way to get the next key of a Python 3.6+ (which are ordered)
For example:
dict = {'one':'value 1','two':'value 2','three':'value 3'}
What I am trying to achieve is a function to return the next key. something like:
next_key(dict, current_key='two') # -> should return 'three'
This is what I have so far:
def next_key(dict,key):
key_iter = iter(dict) # create iterator with keys
while k := next(key_iter): #(not sure if this is a valid way to iterate over an iterator)
if k == key:
#key found! return next key
try: #added this to handle when key is the last key of the list
return(next(key_iter))
except:
return False
return False
well, that is the basic idea, I think I am close, but this code gives a StopIteration error. Please help.
Thank you!
An iterator way...
def next_key(dict, key):
keys = iter(dict)
key in keys
return next(keys, False)
Demo:
>>> next_key(dict, 'two')
'three'
>>> next_key(dict, 'three')
False
>>> next_key(dict, 'four')
False
Looping while k := next(key_iter) doesn’t stop correctly. Iterating manually with iter is done either by catching StopIteration:
iterator = iter(some_iterable)
while True:
try:
value = next(iterator)
except StopIteration:
# no more items
or by passing a default value to next and letting it catch StopIteration for you, then checking for that default value (but you need to pick a default value that won’t appear in your iterable!):
iterator = iter(some_iterable)
while (value := next(iterator, None)) is not None:
# …
# no more items
but iterators are, themselves, iterable, so you can skip all that and use a plain ol’ for loop:
iterator = iter(some_iterable)
for value in iterator:
# …
# no more items
which translates into your example as:
def next_key(d, key):
key_iter = iter(d)
for k in key_iter:
if k == key:
return next(key_iter, None)
return None
You can get the keys of the dictionary as list and use index() to get the next key. You can also check for IndexError with try/except block:
my_dict = {'one':'value 1','two':'value 2','three':'value 3'}
def next_key(d, key):
dict_keys = list(d.keys())
try:
return dict_keys[dict_keys.index(key) + 1]
except IndexError:
print('Item index does not exist')
return -1
nk = next_key(my_dict, key="two")
print(nk)
And you better not use dict, list etc as variable names.
# Python3 code to demonstrate working of
# Getting next key in dictionary Using list() + index()
# initializing dictionary
test_dict = {'one':'value 1','two':'value 2','three':'value 3'}
def get_next_key(dic, current_key):
""" get the next key of a dictionary.
Parameters
----------
dic: dict
current_key: string
Return
------
next_key: string, represent the next key in dictionary.
or
False If the value passed in current_key can not be found in the dictionary keys,
or it is last key in the dictionary
"""
l=list(dic) # convert the dict keys to a list
try:
next_key=l[l.index(current_key) + 1] # using index method to get next key
except (ValueError, IndexError):
return False
return next_key
get_next_key(test_dict, 'two')
'three'
get_next_key(test_dict, 'three')
False
get_next_key(test_dict, 'one')
'two'
get_next_key(test_dict, 'NOT EXISTS')
False

checking if key's already in dictionary with try except

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

How to check if a dictionary is empty?

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

Handle undeclared dict key in Python

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.

Categories