0

I have a question that is similar to this question, but mine concerns multidimentional lists like this:

myList = [['abc', 'abc-321'], ['def', '789-abc'], ['xyz', 'xyz-123']]
newList = []

I want to search this myList for a certain word/phrase, and if there are matches, the entire sublist to be appended to newList, with a way to control with elements are searched

For example, If I search for the the tern 'abc' in the first and second element of each sublist, newList should be (two matches):

[['abc', 'abc-321'], ['def', '789-abc']]

but if only the first element is to be searched, newList should be (only one match):

[['abc', 'abc-402']]

How can I do both types of searches in the most efficient way? Please consider this: The list to be searched contains around a thousand sublists and the text to be searched is about 1-2 paragraphs on average.

Community
  • 1
  • 1
userBG
  • 6,860
  • 10
  • 31
  • 39

3 Answers3

1

Try This

def foo(myList,key,first=True):
    if first: #First Element Search
        return [x for x in myList if key in x]
    else: #Search Both Element
        return [x for x in myList if key in x or key in x[1]]

>>> foo(myList,'abc',0)
[['abc', 'abc-321']]
>>> foo(myList,'abc',1)
[['abc', 'abc-321'], ['def', '789-abc']]

Note: This simply utilized List Comprehension. The only thing to note is the comparison. Comparing two string with in will try to match the first string any where in the second string. Comparing a string with a list, it will try to match the first string anywhere in the first element of the string.

A simpler implementation

def foo(myList,key,first=True):
    return [x for x in myList if key in x or not first and key in x[1]]

>>> foo(myList,'abc')
[['abc', 'abc-321']]
>>> foo(myList,'abc',first=False)
[['abc', 'abc-321'], ['def', '789-abc']]
>>> foo(myList,'abc',first=True)
[['abc', 'abc-321']]    
Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • Thanks, this worked great. I wonder if there is any significant performance diff between the `if any()` way vs your way – userBG Dec 29 '11 at 04:07
  • Usually if there are just two elements I would prefer to use `or` / `and` and if there are more than two elements `any`/`all` would be preferred. When Things are obvious no point of adding an extra level of complexity – Abhijit Dec 29 '11 at 04:12
  • I would strongly recommend making separate functions for the two cases. The functionality isn't really that similar. – Karl Knechtel Dec 29 '11 at 10:43
  • @ofko: `if any()` and `foo()` lead to different results e.g., `foo()` incorrectly returns empty list for `myList = [['abc-1', 'def']]` whereas `if any()` works correctly and matches the item. [Demo](http://ideone.com/Vb505). – jfs Dec 29 '11 at 15:22
1

or:

def bar(L, S):
    return list( v for v in L if any(S in s for s in v) )
Dan D.
  • 73,243
  • 15
  • 104
  • 123
0
[lst for lst in myList if any('abc' in s for s in lst)]

if only the first element is to be searched:

[lst for lst in myList if 'abc' in lst[0]]
jfs
  • 399,953
  • 195
  • 994
  • 1,670