1

If I have an list of strings:

matches = [ 'string1', 'anotherstring', 'astringystring' ]

And I have another string that I want to test:

teststring = 'thestring1'

And I want to test each string, and if any match, do something. I have:

match = 0
for matchstring in matches:
  if matchstring in teststring:
    match = 1
if !match:
  continue

This is in a loop, so we just go around again if we don't get a match (I can reverse this logic of course and do something if it matches), but the code looks clumsy and not pythonic, if easy to follow.

I am thinking there is a better way to do this, but I don't grok python as well as I would like. Is there a better approach?

Note the "duplicate" is the opposite question (though the same answer approach is the same).

Paul
  • 538
  • 6
  • 23

3 Answers3

5

You could use any here

Code:

if any(matchstring in teststring for matchstring in matches):
    print "Matched"

Notes:

  • any exits as soon it see's a match.
  • As per as the loop what is happening is for matchstring in matches here each string from the matches is iterated.
  • And here matchstring in teststring we are checking if the iterated string is in the defined check string.
  • The any will exit as soon as it see's a True[match] in the expression.
Community
  • 1
  • 1
The6thSense
  • 8,103
  • 8
  • 31
  • 65
  • Yes, I wasn't aware of `any` – Paul Feb 18 '16 at 09:24
  • Though I cannot follow the `x in y for x in z` - how is that working? – Paul Feb 18 '16 at 09:26
  • 1
    `in` operator for strings checks for substring occurence, `for o in seq` iterates over sequence. These are two different functionalities with same keyword used. – Łukasz Rogalski Feb 18 '16 at 09:27
  • @Rogalski Yes, I understand the two uses of `in`, I just don't understand how the matchstring created in the `for` can be tested at the beginning – Paul Feb 18 '16 at 09:31
  • @Paul added see if it makes sense. – The6thSense Feb 18 '16 at 09:32
  • @Paul it's simply how scopes in comprehensions are designed. See related question: http://stackoverflow.com/questions/20639180/python-list-comprehension-explained – Łukasz Rogalski Feb 18 '16 at 09:33
  • @The6thSense I understand what it is doing, I just don't understand the underlying mechanic that allows the output from the `for` iterator be used in a test that precedes it on the line. – Paul Feb 18 '16 at 09:34
  • @Paul that is the syntax for `list,dict,set etc.,.` comprehension. You may want to look at the link given by Rogalski. – The6thSense Feb 18 '16 at 09:36
  • @The6thSense Yes, I did (thanks Rogalski), I am absorbing. – Paul Feb 18 '16 at 09:38
  • It was confusing for me too initially when I came across `comprehension.` – The6thSense Feb 18 '16 at 09:39
1

If you want to know what the first match was you can use next:

match = next((match for match in matches if match in teststring), None)

You have to pass None as the second parameter if you don't want it to raise an exception when nothing matches. It will use the value as the default, so match will be None if nothing is found.

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
0

How about you try this:

len([ x for x in b if ((a in x) or (x in a)) ]) > 0

I've updated the answer to check the substring both ways. You can pick and choose or modify as you see fit but I think the basics should be pretty clear.

siphr
  • 421
  • 4
  • 12
  • This would evaluate every string in matches even if you matched the first string and create a list to throw away. – Padraic Cunningham Feb 18 '16 at 09:41
  • True that it goes a step further in also counting the matches and maybe not required for this step but then again it might be. – siphr Feb 18 '16 at 09:43
  • sum with a generator expression would also count the matches and avoid the need to store a list, this is not a use case for a list comp and len. – Padraic Cunningham Feb 18 '16 at 09:47