0

Python 3.7.3

I have a list of lines and I want a single statement to test if a value is contained by any of the lines:

 >>> data=[["red blue green yellow"],["peter ann jack beatrice"]]
 >>> "ann" in data
 False

I want this to be True.

Is there a single statement test, without explicit iteration, that will return True for "ann" or any of the single values in the two lists.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Stephen Boston
  • 971
  • 1
  • 12
  • 23

2 Answers2

1
'ann' in ' '.join(sum(data,[]))
ComplicatedPhenomenon
  • 4,055
  • 2
  • 18
  • 45
  • This works -- but I have no idea why. The 'sum' really throws me off. Could you explain? I can look it up, I know, but it would be interesting for people like me to see your reasoning here. – Stephen Boston Sep 02 '19 at 01:04
  • @StephenBoston `sum(data,[])` is to flatten the nested list, It works as `data[0]+data[1]+...` – ComplicatedPhenomenon Sep 02 '19 at 01:13
  • `sum` will concatenate all strings together (which means if you have a list of `["fish", "cakes"]`, then "shca" will return true. Don't sacrifice accuracy and readability for the sake of cramming it on one line. It'll only bring you bugs, especially when you don't understand the code (as you've said in your comment) – Shadow Sep 02 '19 at 01:15
  • @Shadow thanks, I should separate the item in the list with whitespace. – ComplicatedPhenomenon Sep 02 '19 at 01:25
0

You need to go deeper.

At the moment, you're checking to see if any elements in the parent list is equal to the string "ann" - which isn't the case. So you'll need to iterate over each element and check it.

This is an untested recursive example, which will go through any list looking for your substring. It should either work, or give you inspiration to complete your task.

def check_for_substrings_in_list(substring, parent_list):
    for data in parent_list:
        if isinstance(data, list):
            if check_for_substrings_in_list(substring, data):
                return True
        elif isinstance(data, string) and substring in data:
            return True
    return False
Shadow
  • 8,749
  • 4
  • 47
  • 57
  • This uses an explicit iteration -- which I want to avoid. Looking for a one-line. – Stephen Boston Sep 02 '19 at 01:01
  • One line still does an 'explicit iteration'. Trust me - readability is much more important than trying to cram everything together. And once you've written this function, you only need one line to call it anyway. – Shadow Sep 02 '19 at 01:13
  • Oh I trust that for many contexts readibility is just the thing, but I enjoy exploring the language. And 'readability' is subjective, yes? – Stephen Boston Sep 02 '19 at 01:32
  • Readability is subjective only to a given degree. But in this case I'm more worried about the bugs. Take the accepted solution - there are plenty of ways to get false positives. Only you can work out whether they're likely to bite you, but I personally wouldn't take the risk. – Shadow Sep 02 '19 at 01:48