Use a generator together with any, which short-circuits on the first True:
if any(ext in url_string for ext in extensionsToCheck):
print(url_string)
EDIT: I see this answer has been accepted by OP. Though my solution may be "good enough" solution to his particular problem, and is a good general way to check if any strings in a list are found in another string, keep in mind that this is all that this solution does. It does not care WHERE the string is found e.g. in the ending of the string. If this is important, as is often the case with urls, you should look to the answer of @Wladimir Palant, or you risk getting false positives.
Answer from Lauritz V. Thaulow on Stack OverflowUse a generator together with any, which short-circuits on the first True:
if any(ext in url_string for ext in extensionsToCheck):
print(url_string)
EDIT: I see this answer has been accepted by OP. Though my solution may be "good enough" solution to his particular problem, and is a good general way to check if any strings in a list are found in another string, keep in mind that this is all that this solution does. It does not care WHERE the string is found e.g. in the ending of the string. If this is important, as is often the case with urls, you should look to the answer of @Wladimir Palant, or you risk getting false positives.
extensionsToCheck = ('.pdf', '.doc', '.xls')
'test.doc'.endswith(extensionsToCheck) # returns True
'test.jpg'.endswith(extensionsToCheck) # returns False
>>> all(x in 'tomato' for x in ['t','o','m','a'])
True
>>> all(x in 'potato' for x in ['t','o','m','a'])
False
def myfun(str,list):
for a in list:
if not a in str:
return False
return True
return true must be outside the for loop, not just after the if statement, otherwise it will return true just after the first letter has been checked. this solves your code's problem :)
I have a list, that takes inputs from the user, this means it can change size; for example: list = ["test", "do"] or list = ["a", "b", "c"]
I want to check if variable string, contains all the substrings in list.
I thought if I used:
if list in string: that would work, but it didn't, TypeError: 'in <string>' requires string as left operand, not list
Is there another function/method for this? Or am I going to have to loop len(list) times (I really don't want to do that, because I check hundreds of changing strings)?
You could try
if all([val in string for val in list]):
Which checks the truth of each check and returns True only if all are True. Otherwise you're looking at a loop (or if your lists get really big a generator).
I don't really understand your question, but the easiest to understand solution is probably
if len(set(sub) - set(super)) > 0:
Another one, straightforward, but more complex, is
if all(el in sub for el in super):
Just use all() and check for types with isinstance().
>>> l = ["one", "two", 3]
>>> all(isinstance(item, str) for item in l)
False
>>> l = ["one", "two", '3']
>>> all(isinstance(item, str) for item in l)
True
Answering @TekhenyGhemor's follow-up question: is there a way to check if no numerical strings are in a list. For example: ["one", "two", "3"] would return false
Yes. You can convert the string to a number and make sure that it raises an exception:
def isfloatstr(x):
try:
float(x)
return True
except ValueError:
return False
def valid_list(L):
return all((isinstance(el, str) and not isfloatstr(el)) for el in L)
Checking:
>>> valid_list(["one", "two", "3"])
False
>>> valid_list(["one", "two", "3a"])
True
>>> valid_list(["one", "two", 0])
False
In [5]: valid_list(["one", "two", "three"]) Out[5]: True
Say I have a list of strings like: ["Hey dude", "Hey bro", "Sup dude", "Hey bud"]
How do I check if *any* of those strings in the list contain the word "Sup"?Alternatively, in my case, I could also check if *all* of the strings contain "Hey" , which I also don't know how to do.
(Sorry, I'm new to Python)
Edit: Thank you so much for all the help, guys <3
str1 = "45892190"
lis = [89,90]
for i in lis:
if str(i) in str1:
print("The value " + str(i) + " is in the list")
OUTPUT:
The value 89 is in the list
The value 90 is in the list
If you want to check if all the values in lis are in str1, the code of cricket_007
all(str(l) in str1 for l in lis)
out: True
is what you are looking for
If no overlap is allowed, this problem becomes much harder than it looks at first. As far as I can tell, no other answer is correct (see test cases at the end).
Recursion is needed because if a substring appears more than once, using one occurence instead of the other could prevent other substrings to be found.
This answer uses two functions. The first one finds every occurence of a substring in a string and returns an iterator of strings where the substring has been replaced by a character which shouldn't appear in any substring.
The second function recursively checks if there's any way to find all the numbers in the string:
def find_each_and_replace_by(string, substring, separator='x'):
"""
list(find_each_and_replace_by('8989', '89', 'x'))
# ['x89', '89x']
list(find_each_and_replace_by('9999', '99', 'x'))
# ['x99', '9x9', '99x']
list(find_each_and_replace_by('9999', '89', 'x'))
# []
"""
index = 0
while True:
index = string.find(substring, index)
if index == -1:
return
yield string[:index] + separator + string[index + len(substring):]
index += 1
def contains_all_without_overlap(string, numbers):
"""
contains_all_without_overlap("45892190", [89, 90])
# True
contains_all_without_overlap("45892190", [89, 90, 4521])
# False
"""
if len(numbers) == 0:
return True
substrings = [str(number) for number in numbers]
substring = substrings.pop()
return any(contains_all_without_overlap(shorter_string, substrings)
for shorter_string in find_each_and_replace_by(string, substring, 'x'))
Here are the test cases:
tests = [
("45892190", [89, 90], True),
("8990189290", [89, 90, 8990], True),
("123451234", [1234, 2345], True),
("123451234", [2345, 1234], True),
("123451234", [1234, 2346], False),
("123451234", [2346, 1234], False),
("45892190", [89, 90, 4521], False),
("890", [89, 90], False),
("8989", [89, 90], False),
("8989", [12, 34], False)
]
for string, numbers, should in tests:
result = contains_all_without_overlap(string, numbers)
if result == should:
print("Correct answer for %-12r and %-14r (%s)" % (string, numbers, result))
else:
print("ERROR : %r and %r should return %r, not %r" %
(string, numbers, should, result))
And the corresponding output:
Correct answer for '45892190' and [89, 90] (True)
Correct answer for '8990189290' and [89, 90, 8990] (True)
Correct answer for '123451234' and [1234, 2345] (True)
Correct answer for '123451234' and [2345, 1234] (True)
Correct answer for '123451234' and [1234, 2346] (False)
Correct answer for '123451234' and [2346, 1234] (False)
Correct answer for '45892190' and [89, 90, 4521] (False)
Correct answer for '890' and [89, 90] (False)
Correct answer for '8989' and [89, 90] (False)
Correct answer for '8989' and [12, 34] (False)
To check for the presence of 'abc' in any string in the list:
xs = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in xs):
...
To get all the items containing 'abc':
matching = [s for s in xs if "abc" in s]
Just throwing this out there: if you happen to need to match against more than one string, for example abc and def, you can combine two comprehensions as follows:
matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]
Output:
['abc-123', 'def-456', 'abc-456']
all() stops at the first item evaluates to False. Basically:
if all(isinstance(x, (int, float)) for x in my_list):
print("all numbers!")
else:
print("not all number!")
And using these C-level functions instead of comprehensions should be more performant:
from itertools import repeat
if all(map(isinstance, my_list, repeat((int, float)))):
print("all numbers!")
else:
print("not all number!")
I can't think of any other way to check a sequence than to check the sequence whether you do it explicitly with a for loop, or implicitly with a higher level construct. Given that, you might consider something like this if your intent is to "end the program" upon finding a non-numeric value in the list as stated.
Example:
my_list = [1,2,3,4,6,7,"8"]
for value in my_list:
if not isinstance(value, (int, float)):
raise TypeError(f"Expected only numeric types, found {type(value)} in sequence.")
Output:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-791ea7c7a43e> in <module>
3 for value in my_list:
4 if not isinstance(value, (int, float)):
----> 5 raise TypeError(f"Expected only numeric types, found {type(value)} in sequence.")
TypeError: Expected only numeric types, found <class 'str'> in sequence.