How can I find out if a list is empty without using the not command?
Here is what I tried:
if list3[0] == []:
print("No matches found")
else:
print(list3)
I am very much a beginner so excuse me if I do dumb mistakes.
In order of preference:
# Good
if not list3:
# Okay
if len(list3) == 0:
# Ugly
if list3 == []:
# Silly
try:
next(iter(list3))
# list has elements
except StopIteration:
# list is empty
If you have both an if and an else you might also re-order the cases:
if list3:
# list has elements
else:
# list is empty
You find out if a list is empty by testing the 'truth' of it:
>>> bool([])
False
>>> bool([0])
True
While in the second case 0 is False, but the list [0] is True because it contains something. (If you want to test a list for containing all falsey things, use all or any: any(e for e in li) is True if any item in li is truthy.)
This results in this idiom:
if li:
# li has something in it
else:
# optional else -- li does not have something
if not li:
# react to li being empty
# optional else...
According to PEP 8, this is the proper way:
• For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
You test if a list has a specific index existing by using try:
>>> try:
... li[3]=6
... except IndexError:
... print 'no bueno'
...
no bueno
So you may want to reverse the order of your code to this:
if list3:
print list3
else:
print "No matches found"
Check its length.
l = []
print len(l) == 0
this is how you would do that
if len(list3) == 0:
print("No matches found")
Python provides an inbuilt any() function to check whether an iterable is empty or not:
>>>list=[]
>>>any(list)
False
The function returns True if the iterable contains a 'True' value, and False otherwise.
However, note that the list [0] also returns False with any().
Related
My question is to write a function which returns the longest string and ignores any non-strings, and if there are no strings in the input list, then it should return None.
my answer:
def longest_string(x):
for i in max(x, key=len):
if not type(i)==str:
continue
if
return max
longest_string(['cat', 'dog', 'horse'])
I'm a beginner so I have no idea where to start. Apologies if this is quite simple.
This is how i would do it:
def longest_string(x):
Strings = [i for i in x if isinstance(i, str)]
return(max(Strings, key=len)) if Strings else None
Based on your code:
def longest_string(x):
l = 0
r = None
for s in x:
if isinstance(s, str) and len(s) > l:
l = len(s)
r = s
return r
print(longest_string([None, 'cat', 1, 'dog', 'horse']))
# horse
def longest_string(items):
try:
return max([x for x in items if isinstance(x, str)], key=len)
except ValueError:
return None
def longest_string(items):
strings = (s for s in items if isinstance(s, str))
longest = max(strings, key=len) if strings else None
return longest
print(longest_string(['cat', 'dog', 'horse']))
Your syntax is wrong (second-to-last line: if with no condition) and you are returning max which you did not define manually. In actuality, max is a built-in Python function which you called a few lines above.
In addition, you are not looping through all strings, you are looping through the longest string. Your code should instead be
def longest_string(l):
strings = [item for item in l if type(item) == str]
if len(strings):
return max(strings, key=len)
return None
You're on a good way, you could iterate the list and check each item is the longest:
def longest_string(x)
# handle case of 0 strings
if len(x) == 0:
return None
current_longest = ""
# Iterate the strings
for i in x:
# Handle nonestring
if type(i) != str:
continue
# if the current string is longer than the longest, replace the string.
if len(i) > len(current_longest):
current_longest = i
# This condition handles multiple elements where none are strings and should return None.
if len(current_longest) > 0:
return current_longest
else:
return None
Since you are a beginner, I recommend you to start using python's built-in methods to sort and manage lists. Is the best when it comes to logic and leaves less room for bugs.
def longest_string(x):
x = filter(lambda obj: isinstance(obj, str), x)
longest = max(list(x), key=lambda obj: len(obj), default=None)
return longest
Nonetheless, you were in a good way. Just avoid using python´s keywords for variable names (such as max, type, list, etc.)
EDIT: I see a lot of answers using one-liner conditionals, list comprehension, etc. I think those are fantastic solutions, but for the level of programming the OP is at, my answer attempts to document each step of the process and be as readable as possible.
First of all, I would highly suggest defining the type of the x argument in your function.
For example; since I see you are passing a list, you can define the type like so:
def longest_string(x: list):
....
This not only makes it more readable for potential collaborators but helps enormously when creating docstrings and/or combined with using an IDE that shows type hints when writing functions.
Next, I highly suggest you break down your "specs" into some pseudocode, which is enormously helpful for taking things one step at a time:
returns the longest string
ignores any non-strings
if there are no strings in the input list, then it should return None.
So to elaborate on those "specifications" further, we can write:
Return the longest string from a list.
Ignore any element from the input arg x that is not of type str
if no string is present in the list, return None
From here we can proceed to writing the function.
def longest_string(x: list):
# Immediately verify the input is the expected type. if not, return None (or raise Exception)
if type(x) != list:
return None # input should always be a list
# create an empty list to add all strings to
str_list = []
# Loop through list
for element in x:
# check type. if not string, continue
if type(element) != str:
pass
# at this point in our loop the element has passed our type check, and is a string.
# add the element to our str_list
str_list.append(element)
# we should now have a list of strings
# however we should handle an edge case where a list is passed to the function that contains no strings at all, which would mean we now have an empty str_list. let's check that
if not str_list: # an empty list evaluates to False. if not str_list is basically saying "if str_list is empty"
return None
# if the program has not hit one of the return statements yet, we should now have a list of strings (or at least 1 string). you can check with a simple print statement (eg. print(str_list), print(len(str_list)) )
# now we can check for the longest string
# we can use the max() function for this operation
longest_string = max(str_list, key=len)
# return the longest string!
return longest_string
how to check if this list is empty?
l = ['',['']]
I tried solutions from how to find if nested lists are empty. but none of them worked.
def isListEmpty(inList):
if isinstance(inList, list): # Is a list
return all( map(isListEmpty, inList) )
return False # Not a list
You should check if the list is falsy/empty first before recursively checking the list items. You can also avoid explicitly returning True or False by using the and and or operators:
def isListEmpty(inList):
return inList == '' or isinstance(inList, list) and (not inList or all(map(isListEmpty, inList)))
Demo: https://repl.it/repls/AccurateSmallOutcome
For lists that actually are empty, the function should simply return True.
def isListEmpty(inList):
if isinstance(inList, list): # Is a list
if len(inList) == 0:
return True
else:
return all(map(isListEmpty, inList))
return False # Not a list
l is not empty in fact. But in this case this code should work:
l = ['',['']]
def isListEmpty(inList):
for char in inList:
if char == '' or ['']:
return True
else:
return False
break
print(isListEmpty(l))
You can use a simple recursive approach with any. Using any would make sure that the recursively search ends as soon as a non empty item is found
>>> def is_non_empty_list (l):
... return any(is_non_empty_list(e) if isinstance(e, list) else e for e in l)
...
>>> def is_empty_list (l):
... return not is_non_empty_list(l)
...
>>> is_empty_list(['', ['']])
True
>>> is_empty_list(['', ['a']])
False
>>>
Try This
l = [' ',[ ]]
def isListEmpty(thisList):
for el in thisList:
if (len(el)==0 and type(el)==list):
print('empty') # Or whatever you want to do if you encounter an empty list
isListEmpty(l)
If you face any problems comment below
How can i test if multiple strings exist in another list? Below is a code example that I started with but doesn't work properly. It should return true if even part of the string is found in the list.
I marked in the comments what the result should return. as you can see they all fail though.
def all_exist(avalue, bvalue):
if avalue == []:
return True
else:
print (all(x in avalue for x in bvalue))
items = ['greg','krista','marie']
all_exist(['greg', 'krista'], items) # true
all_exist(['gre', 'kris'], items) # true
all_exist(['gre', 'purple'], items) # false
Would it be better to convert the second list to a single string and then just test if strings in list exist in it?
You have to check if all of the strings in the first list is contained by any string in the second list:
def all_exist(avalue, bvalue):
return all(any(x in y for y in bvalue) for x in avalue)
items = ['greg','krista','marie']
print(all_exist(['greg', 'krista'], items)) # -> True
print(all_exist(['gre', 'kris'], items)) # -> True
print(all_exist(['gre', 'purple'], items)) # -> False
print(all_exist([], items)) # -> True
We want to loop through the elements in avalue and check if this element is in any of the strings in bvalue. But we want to do all of that inside all as we want to check that all elements in avalue have a match.
Also, if we do the test this way, an empty avalue will return True anyway, so we don't need to tell Python to explicitly do this.
Note that: since you have defined all_exist as a function, it should really return a value, not print the result, so I have changed that for you:
def all_exist(avalue, bvalue):
return all(any(i in j for j in bvalue) for i in avalue)
and some testing shows it works:
>>> all_exist(['greg', 'krista'], items) # true
True
>>> all_exist(['gre', 'kris'], items) # true
True
>>> all_exist(['gre', 'purple'], items) # false
False
I'm a programming semi-noob and am working through Torbjoern Lager's 46 Simple Python Exercises. This is number 10: Define a function overlapping() that takes two lists and returns True if they have at least one member in common, False otherwise. You may use your is_member() function, or the in operator, but for the sake of the exercise, you should (also) write it using two nested for-loops.
def over(list1,list2):
for i in list1:
for j in list2:
return i==j
I thought I had a nice, simple solution, but it can't recognize that the lists overlap, unless the overlapping elements are the first ones.
over(["a","b","c","d"],["e","f","a","h"])
returns False
over(["a","b","c","d"],["a","f","g","h"])
returns True
For some reason, it's not searching through all of the combinations. Any help would be appreciated.
It's not searching through all the combinations because you're returning on the first iteration of the nested loop. You could do this:
def over(list1,list2):
for i in list1:
for j in list2:
if i == j:
return True
return False
This returns True as soon as any overlap is found. If no overlap is ever found, it'll get to the last line and return False.
The problem is that you return i==j on the first iteration. Your function will justs compare list1[0] and list2[0]. The solution is to add if.
Here is an example:
def over(list1,list2):
for i in list1:
for j in list2:
if i == j:
return True
return False
You should be testing with an if as suggested in the other answers as you are returning after the very first iteration but using any would be a nicer approach:
def over(list1,list2):
return any(i ==j for i in list1 for j in list2)
Which is equivalent to:
def over(list1,list2):
for i in list1:
for j in list2:
if i == j:
return True
return False
short circuiting on a match and returning True if there is any match or returning False if there are none.
Or using sets for larger input would be the fastest approach:
def over(list1, list2):
return not set(list1).isdisjoint(list2)
if not set(list1).isdisjoint(list2) is True we have at least one common element.
When you execute the "return" stament de execution stops there, like it happens in Java. It returns true because you have 'a' in the first position in both arrays.
You can try this:
result = False;
for i in list1:
for j in list2:
if i == j:
result=True;
return result
If you want it more efficient:
for i in list1:
for j in list2:
if i == j:
return True;
return False;
I have written a function to check for the existence of a value in a list and return True if it exists. It works well for exact matches, but I need for it to return True if the value exists anywhere in the list entry (e.g. value <= listEntry, I think.) Here is the code I am using for the function:
def isValInLst(val,lst):
"""check to see if val is in lst. If it doesn't NOT exist (i.e. != 0),
return True. Otherwise return false."""
if lst.count(val) != 0:
return True
else:
print 'val is '+str(val)
return False
Without looping through the entire character string and/or using RegEx's (unless those are the most efficient), how should I go about this in a pythonic manner?
This is very similar to another SO question, but I need to check for the existence of the ENTIRE val string anywhere in the list. It would also be great to return the index / indices of matches, but I'm sure that's covered elsewhere on Stackoverflow.
If I understood your question then I guess you need any:
return any(val in x for x in lst)
Demo:
>>> lst = ['aaa','dfbbsd','sdfdee']
>>> val = 'bb'
>>> any(val in x for x in lst)
True
>>> val = "foo"
>>> any(val in x for x in lst)
False
>>> val = "fde"
>>> any(val in x for x in lst)
True
Mostly covered, but if you want to get the index of the matches I would suggest something like this:
indices = [index for index, content in enumerate(input) if substring in content]
if you want to add in the true/false you can still directly use the result from this list comprehension since it will return an empty list if your input doesn't contain the substring which will evaluate to False.
In the terms of your first function:
def isValInLst(val, lst):
return bool([index for index, content in enumerate(lst) if val in content])
where the bool() just converts the answer into a boolean value, but without the bool this will return a list of all places where the substring appears in the list.
There are multiple possibilities to do that. For example:
def valInList1 (val, lst):
# check `in` for each element in the list
return any(val in x for x in lst)
def valInList2 (val, lst):
# join the list to a single string using some character
# that definitely does not occur in val
return val in ';;;'.join(lst)