What is the easiest way to check to see if a list or dict exists in python ?
Im using the following but this isn't working:
if len(list) == 0:
print "Im not here"
Thanks,
For the lists:
if a_list:
print "I'm not here"
The same is for the dicts:
if a_dict:
print "I'm not here"
You can use a try/except block:
try:
#work with list
except NameError:
print "list isn't defined"
When you try to reference a non-existing variable the interpreter raises NameError. It's not safe, however, to rely on the existence of a variable in your code (you'd better initialize it to None or something). Sometimes I used this:
try:
mylist
print "I'm here"
except NameError:
print "I'm not here"
If you're able to name it - it obviously "exists" - I assume you mean to check that it's "non-empty"... The most pythonic method is to use if varname:. Note, this won't work on generators/iterables to check if they will return data as the result will always be True.
If you just want to use a certain index/key, then just try and use it:
try:
print someobj[5]
except (KeyError, IndexError) as e: # For dict, list|tuple
print 'could not get it'
Examples:
mylist=[1,2,3]
'mylist' in locals().keys()
Or use this:
mylist in locals().values()
Simple console test:
>>> if len(b) == 0: print "Ups!"
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> try:
... len(b)
... except Exception as e:
... print e
...
name 'b' is not defined
Examples show how to check if a list has elements:
alist = [1,2,3]
if alist: print "I'm here!"
Output: I'm here!
Otherwise:
alist = []
if not alist: print "Somebody here?"
Output: Somebody here?
If you need to check existence/nonexistence of a list/tuple maybe this can be of help:
from types import ListType, TupleType
a_list = [1,2,3,4]
a_tuple = (1,2,3,4)
# for an existing/nonexisting list
# "a_list" in globals() check if "a_list" is defined (not undefined :p)
if "a_list" in globals() and type(a_list) is ListType:
print "I'm a list, therefore I am an existing list! :)"
# for an existing/nonexisting tuple
if "a_tuple" in globals() and type(a_tuple) is TupleType:
print "I'm a tuple, therefore I am an existing tuple! :)"
If we need to avoid of in globals() maybe we can use this:
from types import ListType, TupleType
try:
# for an existing/nonexisting list
if type(ima_list) is ListType:
print "I'm a list, therefore I am an existing list! :)"
# for an existing/nonexisting tuple
if type(ima_tuple) is TupleType:
print "I'm a tuple, therefore I am an existing tuple! :)"
except Exception, e:
print "%s" % e
Output:
name 'ima_list' is not defined
---
name 'ima_tuple' is not defined
Bibliography:
8.15. types — Names for built-in types — Python v2.7.3 documentation https://docs.python.org/3/library/types.html
Check (1) variable exist and (2) check it is list
try:
if type(myList) is list:
print "myList is list"
else:
print "myList is not a list"
except:
print "myList not exist"
s = set([1, 2, 3, 4])
if 3 in s:
print("The number 3 is in the list.")
else:
print("The number 3 is NOT in the list.")
You can find more about it here: https://docs.quantifiedcode.com/python-anti-patterns/performance/using_key_in_list_to_check_if_key_is_contained_in_a_list.html
Related
I am quite new in Python.
I have to find/compare a string value with a list which is present inside a List of dictionary of dictionary of List. I wrote the code below, though it is working fine but can we write in some better way.
abc = [{'GetDriverPackInfo_OUTPUT': {'OSList': [u'Linux', u'Windows', u'Xen', u'VMware'], 'ReturnValue': [u'0'], 'Version': [u'15.07.04']}}]
os_name = "Linux"
for k in abc: #['GetDriverPackInfo_OUTPUT']['OSList']:
if os_name in k['GetDriverPackInfo_OUTPUT']['OSList']: #== os_name:
print ("os_name found")
else:
print ("os_name not found")
I'm not sure this works for you. It'll work only if abc always has one 'GetDriverPackInfo_OUTPUT' item.
temp = abc[0]['GetDriverPackInfo_OUTPUT']['OSList']
if os_name in temp:
print "found"
else:
print "not found"
In [1]: osname in [j for j in [k['GetDriverPackInfo_OUTPUT']['OSList'] for k in abc]][0]
Out[1]: True
If it's return True the osname exits else it's not.
I would like to find a way to get the variables I assigned before an exception is made. E.G if the code is
try:
a=b
c=d
e=f
except:
bla bla
And an exception is generated at "e=f," I still want a=b and c=d
Is it possible? I realize I could make this multiple try statements but is there something I can do in one step?
Yes, it is perfectly possible. Below is a demonstration:
>>> try:
... a = 1
... b = 2
... c = 1/0 # This will raise a ZeroDivisionError
... except ZeroDivisionError:
... print 'an error occurred'
...
an error occurred
>>> a # a still exists
1
>>> b # so does b
2
>>> c # only c is undefined
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>>
try/except is designed to execute the code in the try-block normally until an exception is raised. When that happens, the try-block is immediately exited. This means that only the code after the line that raised the exception is ignored.
The best you can do is to limit the number of expressions inside your try block.
If you need to know where the exception is raised, you are probably better off using multiple try...except's like you mentioned in your queestion, since there is no (practical) way to know where the exception was raised.
If the expressions are of the same type, you may want to put them in lists though, and loop over them, like:
vars = [a, b, c]
values = [1, 2, 0]
for i, (var, value) in enumerate(zip(vars, values)):
try:
var /= value
except ZeroDivisionError:
print 'The exception was raised on the {}. iteration'.format(i)
continue
try:
a = "foo"
c = "bar"
e = unknown_function()
except:
pass
print a, c # prints "foo bar"
Both a and c are set, you can simply use their values after the exception is handled. e is not set to anything as an exception was raised when that line was executed.
If I understand you correctly, this will happen by default. Raising an exception does not magically undo everything that has already happened inside the try block. In your example, if an error occurs on the assignment of e, a and c will still have the values they were assigned.
try:
a = b
c = d
e = f # oh noes! error! Try block skips to the end!
except: pass
print (a) #but a and c are still there
print (c)
This is a straight forward method without much of a hassle . This is the best way out when you cant predict what type of error can occur, or multiple errors can occur .
try :
a=10
except :
print "bla A"
try :
b=20
except:
print "bla B"
try:
c=d
except :
print "bla C"
Is it something like this that you want ?
import sys
code = """
b = 100
d = 200
a=b
c=d
e=10/0
g=e
h = 100
"""
for line in filter(None,code.splitlines()):
print line
try:
exec line
except:
sys.excepthook(sys.exc_info()[0],sys.exc_info()[1],None)
result
b = 100
d = 200
a=b
c=d
e=10/0
ZeroDivisionError: integer division or modulo by zero
g=e
NameError: name 'e' is not defined
h = 100
I'm working on a project which used a load of If, Elif, Elif, ...Else structures, which I later changed for switch-like statements, as shown here and here.
How would I go about adding a general "Hey, that option doesn't exist" case similar to an Else in an If, Elif, Else statement - something that gets executed if none of the Ifs or Elifs get to run?
If the else is really not an exceptional situation, would it not be better to use the optional parameter for get?
>>> choices = {1:'one', 2:'two'}
>>> print choices.get(n, 'too big!')
>>> n = 1
>>> print choices.get(n, 'too big!')
one
>>> n = 5
>>> print choices.get(n, 'too big!')
too big!
You could catch the KeyError error that ensues when a value is not found in the map, and return or process there a default value. For example, with n = 3 this piece of code:
if n == 1:
print 'one'
elif n == 2:
print 'two'
else:
print 'too big!'
Becomes this:
choices = {1:'one', 2:'two'}
try:
print choices[n]
except KeyError:
print 'too big!'
Either way, 'too big!' gets printed on the console.
The first article you linked to had a very clean solution:
response_map = {
"this": do_this_with,
"that": do_that_with,
"huh": duh
}
response_map.get( response, prevent_horrible_crash )( data )
This will call prevent_horrible_crash if response is not one of the three choices listed in response_map.
Let's say you have a function f(a,b) and different setups of parameters according to the value of some variable x. So you want to execute f with a=1 and b=3 if x='Monday' and if x='Saturday' you want to execute f with a=5 and b=9. Otherwise you will print that such value of x is not supported.
I would do
from functools import partial
def f(a,b):
print("A is %s and B is %s" % (a,b))
def main(x):
switcher = {
"Monday": partial(f,a=1, b=3),
"Saturday": partial(f, a=5, b=9)
}
if x not in switcher.keys():
print("X value not supported")
return
switcher[x]()
this way f is not executed on declaration of switcher but at the last line.
Some one-line alternatives:
choices = {1:'one', 2:'two'}
key = 3
# returns the provided default value if the key is not in the dictionary
print(choices[key] if key in choices else 'default_value')
# or using the dictionary get() method
print(choices.get(key, 'default_value')
I have a function in python that does error checking on a string. If the function finds an error it will return a tuple with an error code and an identifier for that error. Later in the program I have the function that handles the error. It accepts the tuple into two variables.
errCode, i = check_string(s,pathType)
check_string is the function that produces the tuple. What I want it to does is return just zero if there is no error. When a zero is returned the above code seems to fail because there is nothing for the variable i.
Is there an easy way to get this to work or do I just need to have the program return a tuple of 0 and 0 if no error is found?
I would use the exception system for this.
class StringError(Exception):
NO_E = 0
HAS_Z = 1
def string_checker(string):
if 'e' not in string:
raise StringError('e not found in string', StringError.NO_E)
if 'z' in string:
raise StringError('z not allowed in string', StringError.HAS_Z)
return string.upper()
s = 'testing'
try:
ret = string_checker(s)
print 'String was okay:', ret
except StringError as e:
print 'String not okay with an error code of', e.args[1]
You could use None as the value for error
def check_string(s,pathType):
# No error
return (None, i)
Why not simply check the length of the tuple before trying to retrieve the values?
err_tup = check_String(s, pathType)
if len(err_tup) == 2:
errCode, i = err_tup
else: # assuming it can only be 1 otherwise
errCode = err_tup
This would work without making any changes to the rest of your code that generates the tuple, and is semantically clear.
Based on "Simple is better than complex."
If you are going to return zero:
foo = func()
if not foo:
print 'No errors'
else:
# foo is tuple
I need to either call exec() or eval() based on an input string "s"
If "s" was an expression, after calling eval() I want to print the result if the result was not None
If "s" was a statement then simply exec(). If the statement happens to print something then so be it.
s = "1 == 2" # user input
# ---
try:
v = eval(s)
print "v->", v
except:
print "eval failed!"
# ---
try:
exec(s)
except:
print "exec failed!"
For example, "s" can be:
s = "print 123"
And in that case, exec() should be used.
Ofcourse, I don't want to try first eval() and if it fails call exec()
Try to compile it as an expression. If it fails then it must be a statement (or just invalid).
isstatement= False
try:
code= compile(s, '<stdin>', 'eval')
except SyntaxError:
isstatement= True
code= compile(s, '<stdin>', 'exec')
result= None
if isstatement:
exec s
else:
result= eval(s)
if result is not None:
print result
It sort of sounds like you'd like the user to be able to interact with a Python interpreter from within your script. Python makes it possible through a call to code.interact:
import code
x=3
code.interact(local=locals())
print(x)
Running the script:
>>> 1==2
False
>>> print 123
123
The intepreter is aware of local variables set in the script:
>>> x
3
The user can also change the value of local variables:
>>> x=4
Pressing Ctrl-d returns flow of control to the script.
>>>
4 <-- The value of x has been changed.