python how to check list does't contain any value - python-3.x

consider this simple function
def foo(l=[]):
if not l: print "List is empty"
else : print "List is not empty"
Now let's call foo
x=[]
foo(x)
#List is empty
foo('')
#List is empty
But if x=[''] the list is not considered as empty!!!
x=['']
foo(x)
#List is not empty
Questions -
Why list of empty values are not considered as empty? (In case of variable it is considered as empty e.g.)
x=''
if x:print 'not empty!!'
else: print 'empty'
How can I modify function foo() so that list will be considered as empty in all these cases: x=[] , x=[''], x=['', '']

Using the built-in any()
def foo(l=[]):
if any(l):
print 'List is not empty'
else:
print 'List is empty'
foo([''])
# List is empty

In your examples, the only case where the list really is empty is the one in which there is nothing in the square brackets. In the other examples you have lists with various numbers of empty strings. These are simply different (and in all languages I can think of, the same would be true).

You can use recursive call to the function foo to deal with nested lists.
def foo(l=[]):
if type(l)==list:
return any([foo(x) for x in l])
else:
return bool(l)

First of all: Even an empty string is a string. A list that contains an empty string still contains an element.
while a='' is empty with len = 0, it is regardless for the list, it still contains an element, e.g., mylist = [a] is the same as mylist = [''] but it might be clearer to you. Take a as an element and ignore the content.
To check if elements of a list are empty, iterate over them.
def isEmpty(li=[]):
for elem in li:
if len(elem) > 0: return false
return true

To answer your first question about why a list of empty values is not considered empty, it's because it does contain something, even if those things are themselves empty. Think of it like a box of empty boxes.
The code below shows one way to modify the function foo() to do what you want (and test it). Your notion of what an empty list is was surprisingly tricky to devise, partially because it runs counter to what the language itself considers empty. As you can see all the logic dealing with the determination of whether the list is "empty" according to your definition has been moved into a separate function called empty_list() since that probably has little to do with the rest of what foo() has to accomplish. It's not overly complex and if nothing else should provide you with a good starting point.
Also, you didn't say what it should do if the argument it's passed isn't a list of any kind or was a list but didn't contain just other lists or strings, so as written it will raise a TypeError exception -- something which is similar to the way most built-in Python functions respond when this occurs with them. Below is the sample code and its test output:
try:
string_type = basestring
except NameError: # probably Python 3.x
string_type = str
class _NULL(object): # unique marker object
def __repr__(self): return '<nothing>'
_NULL = _NULL()
def empty_list(arg=_NULL):
arg = arg if arg is not _NULL else []
if not isinstance(arg, (list, string_type)):
raise TypeError
elif isinstance(arg, string_type):
return not len(arg)
else:
return len(arg) == 0 or all(empty_list(e) for e in arg)
def foo(list_=None):
if list_ is None or empty_list(list_):
print 'list is empty'
else:
print 'list is not empty'
testcases = [
_NULL,
[],
[''],
['', ''],
['', ['']],
['abc'],
['', 'abc'],
[False],
[None],
[0],
[0.0],
[0L],
[0j],
[42],
[{}],
[{'':0}],
[{'a':1}],
False,
None,
0,
0.0,
0L,
0j,
42,
{},
{'':0},
{'a':1},
]
for arg in testcases:
call = 'foo( {!r:s} ) ->'.format(arg)
print '{!s:>20s}'.format(call),
try:
foo() if arg is _NULL else foo(arg)
except TypeError:
print 'illegal argument exception'
Here's the output it produces with Python 2.7:
foo( <nothing> ) -> list is empty
foo( [] ) -> list is empty
foo( [''] ) -> list is empty
foo( ['', ''] ) -> list is empty
foo( ['', ['']] ) -> list is empty
foo( ['abc'] ) -> list is not empty
foo( ['', 'abc'] ) -> list is not empty
foo( [False] ) -> illegal argument exception
foo( [None] ) -> illegal argument exception
foo( [0] ) -> illegal argument exception
foo( [0.0] ) -> illegal argument exception
foo( [0L] ) -> illegal argument exception
foo( [0j] ) -> illegal argument exception
foo( [42] ) -> illegal argument exception
foo( [{}] ) -> illegal argument exception
foo( [{'': 0}] ) -> illegal argument exception
foo( [{'a': 1}] ) -> illegal argument exception
foo( False ) -> illegal argument exception
foo( None ) -> list is empty
foo( 0 ) -> illegal argument exception
foo( 0.0 ) -> illegal argument exception
foo( 0L ) -> illegal argument exception
foo( 0j ) -> illegal argument exception
foo( 42 ) -> illegal argument exception
foo( {} ) -> illegal argument exception
foo( {'': 0} ) -> illegal argument exception
foo( {'a': 1} ) -> illegal argument exception

The list [''] is, indeed, not empty. It contains an empty string. The string is empty, the list is not. If you want to find these lists, check if the list is empty, and if not, check if every entry is ''.

Related

How to modify list of lists using str.format() so floats are 3 decimals and other data types remain the same

I have a list of lists that is very big, and looks like this:
list_of_lists = [[0,'pan', 17.892, 4.6555], [4, 'dogs', 19.2324, 1.4564], ...]
I need to modify it using the str.format() so the floats go to 3 decimal places and the rest of the data stays in its correct format. I also need to add a tab between each list entry so it looks organized and somewhat like this:
0 'pan' 17.892 4.655
4 'dogs' 19.232 1.456
...
And so on.
My problem is that I keep getting the error in my for loop and gow to fix it.
for x in list_of_lists:
print ("{:.2f}".format(x))
TypeError: unsupported format string passed to list.__format__
In your loop you are iterating through a nested list. This means that x is also a list itself, and not a valid argument to the format() function.
If the number of elements in the inner lists are small and it makes sense in the context of the problem, you can simply list all of them as arguments:
list_of_lists = [[0,'pan', 17.892, 4.6555], [4, 'dogs', 19.2324, 1.4564]]
for x in list_of_lists:
print ("{:d}\t{:s}\t{:.3f}\t{:.3f}".format(x[0], x[1], x[2], x[3]))
These are now tab delimited, and the floats have three decimal places.
for x in list_of_lists:
print ("{:.2f}".format(x))
This is only looping over the top level array - not the elements inside - therefore you are getting the error.
Try addressing the element individually
# build manually, join with tab-char and print on loop
for i in s:
result = []
result.append( f'{i[0]}' )
result.append( f'{i[1]}' )
result.append( f'{i[2]:.3f}' )
result.append( f'{i[3]:.3f}' )
print( '\t'.join(result) )
# build in one line and print
for i in s:
print( f'{i[0]}\t\'{i[1]}\'\t{i[2]:.3f}\t{i[3]:.3f}'
Or as a list comprehension
# build whole line from list comprehension, join on new-line chat
result = [f'{i[0]}\t\'{i[1]}\'\t{i[2]:.3f}\t{i[3]:.3f}' for i in s]
result = '\n'.join(result)
print(result
# all in one line
print( '\n'.join([f'{i[0]}\t\'{i[1]}\'\t{i[2]:.3f}\t{i[3]:.3f}' for i in s]))

How to check if the item in a nested list in a dictionary is a float?

I am currently trying to do something like a calculator where invalid inputs produce an error. For the purpose of this exercise, each item in the list is split with a space. split( ) However, I am running into a problem if the input is a float.
I am unable to import any libraries
def get_valid_numbers(exprlist):
for n, token in enumerate(exprlist):
if token.isalpha():
print(f"Invalid expression, expecting operand between {' '.join(exprlist[:n])} and {' '.join(exprlist[n+1:])} but {exprlist[n]} is a variable")
return False
if token != float and token not in '(+-**//)':
print(f"Invalid expression, expecting operand between {' '.join(exprlist[:n+1])} and {' '.join(exprlist[n+1:])}")
return False
return True
I entered a float but it still returned the error message
def main():
while True:
expr = input('Enter expression: ')
if expr == '':
print('Application ended')
break
exprlist = expr.split()
if get_valid_numbers(exprlist):
eval(expr)
else:
continue
The expected output is that the program is to check if the token is not a float OR does not contain one of the operators and operands "(+-**//)". If it is a float or contains one of the operators or operand, it should return True
Checking type should be done with isinstance(). For example:
a = 5.4
isinstance(a, float)
>>> True
You can also check type with type(). For example:
b = 2
type(b) is float
>>> False
isinstance() is the preferred method to use.

why my code returns TypeError: 'NoneType' object is not iterable? [duplicate]

This question already has answers here:
What causes my function to return None at the end? [duplicate]
(5 answers)
Closed 3 years ago.
i am trying to define a function which checks strings whether they contains the word from a dictionary and return true along with which word matched . Below is the snippet of code , everything works fine when a word matches in the string from dictionary.
def trigcheck(strings,a):
try:
str = strings.split()
m=''
a_match = [True for match in a if match in str]
a=[m for m in a if m in str]
if True in a_match:
return True,a[0]
except:
return False,""
bool1,w=trigcheck("kjfdsnfbdskjhfbskdabs",['hello','do'])
print(bool1)
print(w)
I was expecting that with string that doesn't match should return False and ' ' . But it throws error saying:
bool1,w=trigcheck("kjfd s n f dobdskjhfbskdabs",['hello','do'])
TypeError: 'NoneType' object is not iterable
If you don't raise an exception, and True is not in a_match, you don't explicitly return at all, causing you to return None implicitly. Unpacking None to bool1 and w is what raises the exception.
Fix your code by making the exceptional return unconditional if the if check fails:
def trigcheck(strings,a):
try:
str = strings.split()
m=''
a_match = [True for match in a if match in str]
a=[m for m in a if m in str]
if True in a_match:
return True,a[0]
except Exception: # Don't use bare except unless you like ignoring Ctrl-C and the like
pass
# Failure return is outside except block, so fallthrough reaches
# it whether due to an exception or because the if check failed
return False,""
Additional side-note: Your test for a match existing is relatively inefficient; it can't short-circuit, and requires a temporary list. Replacing the body of your function with the following code which relies on your exception handling to return when there are no matches:
def trigcheck(strings,a):
try:
strings = strings.split() # Don't nameshadow builtins, reuse strings instead of shadowing str
return True, next(m for m in a if m in strings)
except StopIteration:
return False, ""
reduces three scans and a two temporary lists to a single scan and no temporary lists, and avoids silencing random exceptions (e.g. a TypeError because someone passed a non-string or non-iterable as an argument) by only catching the one that indicates a failure to find a match.

Why does Python 3 print statement appear to alter a variable, declared later in the code, but works fine without it?

I am running Python 3.6.2 on Windows 10 and was learning about the zip() function.
I wanted to print part of the object returned by the zip() function.
Here is my code, without the troublesome print statement:
a = ("John", "Charles", "Mike")
b = ("Jenny", "Christy", "Monica", "Vicky")
x = zip(a, b)
tup = tuple(x)
print(tup)
print(type(tup))
print(len(tup))
print(tup[1])
Here is my code with the troublesome print statement:
a = ("John", "Charles", "Mike")
b = ("Jenny", "Christy", "Monica", "Vicky")
x = zip(a, b)
print(tuple(x)[1])
tup = tuple(x)
print(tup)
print(type(tup))
print(len(tup))
print(tup[1])
The print(tuple(x)[1]) statement appears to change the tuple 'tup' into a zero-length one and causes the print(tup[1]) to fail later in the code!
In this line, you create an iterator:
x = zip(a, b)
Within the print statement, you convert the iterator to a tuple. This tuple has 3 elements. This exhausts the iterator and anytime you call it afterwards, it will return no further elements.
Therefore, upon your creation of tup, your iterator does not return an element. Hence, you have a tuple with length 0. And of course, this will raise an exception when you try to access the element with index 1.
For testing, consider this:
a = ("John", "Charles", "Mike")
b = ("Jenny", "Christy", "Monica", "Vicky")
x = zip(a, b)
tup1 = tuple(x)
tup2 = tuple(x)
print(tup1)
print(tup2)
It will give you the following result:
(('John', 'Jenny'), ('Charles', 'Christy'), ('Mike', 'Monica'))
()
This is basically what you do when creating a tuple out of an iterator twice.

Trying to compare two strings. Fails because string is always prepended with u"foobar"

I have two lists
list1 = ["foo", "bar"]
list2 = ["foo", "bar"]
I have a method text_match which compares two strings:
def text_match(self, expected, actual):
if expected == actual:
return True
else:
return False
I call the method
self.text_match(list1[0], list2[0])
I get false.
When i print the two strings from the list
list1[0] >> foo
list2[1] >> u"foo"
Why are they not the same when printed?
I've tried encoding, decoding, converting to string.
Nothing works.
Any ideas?
def text_match(self, expected, actual):
if expected == actual:
return True
else:
return False
This Error Will Never Give A Chance to the script to Work
Return Flase Couldn't Be In the Same Indent with else:

Resources