0

I have a list of values which are of different types and I would like to check if a substring exists in the given list and when found, I want to get back the index of it.

I tried doing it with any() but it throws me an error saying in <string>' requires string as left operand, not int. I am assuming, all the values in the list needs to be string in order to use any(). What other way I could use to achieve this?

Here is my Current code:

list_val = [1,18.0, 'printer', 'EXTRACT (123)']
string_val = 'EXTRACT'
any(x in string_val for x in list_val)

I even tried converting all the non-strings into strings and then wanted to use the above any() logic, but that was giving me other errors. I tried the following:

for i, val in enumerate(list_val):
    if not isinstance(val, str):
        list_val[i] = str(val)

This throws me the error: isinstance() arg 2 must be a type or tuple of types

3
  • You'd use string_val in x, to begin with. Commented Sep 9, 2019 at 21:08
  • based on your error message, I presume you overwrote the str type. Try print(str) to check. If the output is not <type 'str'>, that's a problem. Commented Sep 9, 2019 at 21:11
  • Your second exception indicates you have masked the built-in type by binding something else to the name str. Get rid of it with del str. Commented Sep 9, 2019 at 21:12

1 Answer 1

4

Just filter your list on strings and only test against those that pass the filter:

any(string_val in item for item in list_val if isinstance(item, str))

Demo:

>>> list_val = [1,18.0, 'printer', 'EXTRACT (123)']
>>> string_val = 'EXTRACT'
>>> any(string_val in item for item in list_val if isinstance(item, str))
True

Note that I used string_val in item, not item in string_val; your example list makes it clear you want to see if there are any elements that contain EXTRACT, not if there are elements that are a substring of EXTRACT (e.g. 'EXT', 'RACT', etc.).

Your second attempt only failed because you appear to have assigned something else to the name str, because the isinstance() call is otherwise correct:

>>> isinstance("foo", str)
True
>>> str = "spam"
>>> isinstance("foo", str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or tuple of types
>>> del str
>>> isinstance("foo", str)
True

The problem is trivially fixed by removing the str binding again, as I did above You'll have to anyway, as you'll see the same exception using any() with an isinstance() filter.

Not that you need to alter list_val at all for any() to work, however.

Sign up to request clarification or add additional context in comments.

5 Comments

Your answer still gives me the following TypeError Traceback (most recent call last) <ipython-input-42-752296da52ed> in <module> ----> 1 any(string_val in item for item in list_val if isinstance(item, str)) <ipython-input-42-752296da52ed> in <genexpr>(.0) ----> 1 any(string_val in item for item in list_val if isinstance(item, str)) TypeError: isinstance() arg 2 must be a type or tuple of types
@Tums: yes, because you still have rebound str. Remove that. str is not resolving to the built-in type but to something else.
You are absolutely right. I was using Jupyter and I deleted that cell and I didn't realize it was still in the namespace.
How can I tweak the above code to make it work with a list of string values something like this: string_val = ['EXTRACT', 'SUBTRACT', 'DEDUCT', 'ADDIT', 'CLEAR']. That is I want to check if any of these strings exists in the given list_val. I would be really grateful. Thanks.
@Tums either nest another any() loop inside (any(v in item for v in string_val) for item in list_val)) or use a regex instead (any(re.search(r’(EXTRACT|SUBTRACT|DEDUCT|ADDIT|CLEAR)', item) for item in list_val).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.