0

My aim is to create a conditional where: if one of the strings is in the list it gets printed. I tried the following and stuck with this:

Why the output of this code:

strings = ['sdksudfhdsf', 'other', 'sdfsdfwirfkdf', 'another', 'sqdiusaqwe']
substring = 'some_string' or 'other' or 'another' or 'different'

strings_with_substring = [string for string in strings if substring in string]

print(strings_with_substring)

is an empty list

but the above returns the proper values:

strings = ['sdksudfhdsf', 'other', 'sdfsdfwirfkdf', 'another', 'sqdiusaqwe']
substring = 'other' or 'another' or 'different' or 'some_string'

strings_with_substring = [string for string in strings if substring in string]

print(strings_with_substring)

output:

['other', 'another']

Please note that the only thing which I did is to move a 'some_string' to the end of a variable 'substring'

Michal K
  • 69
  • 1
  • 7
  • 1
    Print `substring` after you assigned it, to see what (partly) goes wrong. – 9769953 Dec 16 '21 at 16:56
  • Also: `substring in string` tests if `substring` is *part of* `string`; it is not an "equal to" check. That is `substring == string`. – 9769953 Dec 16 '21 at 16:57
  • Your variable `substring` is always `True` and `True` in {list of strings} will never be `True`. – kalatabe Dec 16 '21 at 16:57
  • 2
    @blackbrandt, that's not true in Python. `0 or "hi"` evaluates to `"hi"`, while `[] and "bye"` evaluates to `[]`. – Charles Duffy Dec 16 '21 at 17:00

4 Answers4

2

I would recommend using regex for string pattern matching.

The following could be achieved by defining your regex as all of your possible matches. Please note the pipeline "|" operator is equivalent to or in regex, i.e matching 'some_string' or 'other' etc.

regex = r'some_string|other|another|different'

You can then construct your list as follows:

import re
strings = ['sdksudfhdsf', 'other', 'sdfsdfwirfkdf', 'another', 'sqdiusaqwe']
strings_with_substring = [string for string in strings if re.search(regex, string)]
print(strings_with_substring) # Output: ['other', 'another']

Edit:

I should note that this is any form of match, for instance the regex r"other" will match the string "another".

If you wish to match the entire string, you should use anchors to denote that the string must start and finish with the pattern:

regex = r'^some_string$|^other$|^another$|^different$'
Sam
  • 773
  • 4
  • 13
  • 1
    While this is technically a valid answer, I would not use it. Firstly, it is more than an order of magnitude slower that the answer by @pedro-maia though I imagine that performance is not likely a concern. More importantly, you have to maintain a regex expression rather than just a simple list of substrings. – JonSG Dec 16 '21 at 17:38
  • 1
    I completely agree. I'm used to using regex as I use it a lot for more complex pattern matching so it normally comes to mind first and I offer it as an answer to users so the same principles can be applied to more complex situations. – Sam Dec 16 '21 at 17:42
1

Use set.intersection:

strings = ['sdksudfhdsf', 'other', 'sdfsdfwirfkdf', 'another', 'sqdiusaqwe']
substring = ['other','another','different','some_string']
 
print( set(strings).intersection(substring) )
{'another', 'other'}
Pedro Maia
  • 2,666
  • 1
  • 5
  • 20
1

No regex, plain list and comprehension with a filter

strings = ['sdksudfhdsf', 'other', 'sdfsdfwirfkdf', 'another', 'sqdiusaqwe']
substring = ['different','some_string', 'other','another']
 
print([string for string in strings if string in substring])

Output

['other', 'another']
hpchavaz
  • 1,368
  • 10
  • 16
0

in or operator for example

a = <exp1> or <exp2> or <exp3>

here evaluation start from left to right, and it look for first value which is not False ie not None or False, and set the value to the variable

for eg .

>>> None or None or 1
1
>>>
>>> None or None or 1
1
>>> None or None or None
>>> False or False or False
False
>>> False or False or False or True
True
>>> False or False or False or 'heelo'

so in your first case, sub_string is set to some_string and only this is evaluated in later stage and not found in the list so empty result. substring = 'some_string' or 'other' or 'another' or 'different' which is equivalent to substring = True or True or True or True, since all are true so first true encounter in interpreter is saved/mapped to the assignment variable ie substing. so substring = 'some_stirng'

and in 2nd case sub_string is seted to other which is found in the list and got the result

sahasrara62
  • 10,069
  • 3
  • 29
  • 44