1

So i have two lists a normal list and a nested list say,

list1 = ['john','amal','joel','george']
list2 = [['john'],['jack','john','mary'],['howard','john'],['jude']]

I would like to check if any of the string in list1 is present in list2 and if so, return the indices of the string (which is in both the lists) in list2. Sample code which demonstrates the required output is shown below:

out = [(ind,ind2) for ind,i in enumerate(list2) 
    for ind2,y in enumerate(i) if 'john' in y]
print out

it returns : [(0, 0), (1, 1), (2, 1)]

the above code does output the indices but it is limited to the string that we manually input. Is it possible to do as i have explained above? any help would be appreciated.(fairly new to nested lists). Thanks!

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
Amal Sailendran
  • 341
  • 1
  • 2
  • 16
  • 2
    Possible duplicate of [How to check if a string contains an element from a list in Python](https://stackoverflow.com/questions/6531482/how-to-check-if-a-string-contains-an-element-from-a-list-in-python) – Aran-Fey Apr 07 '18 at 10:10
  • i'm sorry if it is, but i would like a comprehensive answer on this query – Amal Sailendran Apr 07 '18 at 10:12
  • yes i do, i have provided a sample code whose output is what i wish to get – Amal Sailendran Apr 07 '18 at 10:13
  • 1
    They want to check if any of the strings in `list1` is contained in `y`, no? Unless I misunderstood something, that dupe is 100% accurate. Replace `if 'john' in y` with the code from the dupe -> problem solved. – Aran-Fey Apr 07 '18 at 10:13
  • @Aran-Fey: Hi, the link you provided does not answer my question as min uses a nested list rather than a string alone. – Amal Sailendran Apr 07 '18 at 10:16
  • 1
    I don't see how the fact that there's a nested list in your question is relevant to the appropriateness of the dupe _at all_. Does `out = [(ind,ind2) for ind,i in enumerate(list2) for ind2,y in enumerate(i) if any(x in y for x in list1)]` give you the output you want or not? If yes, then it's a duplicate. – Aran-Fey Apr 07 '18 at 10:20

4 Answers4

2
list1 = ['john','amal','joel','george']
list2 = [['john'],['jack','john','mary'],['howard','john'],['jude']]

res = []
for i, m in enumerate(list2):    #Iterate list2 
    for j, n in enumerate(m):    #Iterate nested list
        if n in list1:           #Check if element in list1
            res.append((i, j))   #Append index. 
print res

Output:

[(0, 0), (1, 1), (2, 1)]
Rakesh
  • 81,458
  • 17
  • 76
  • 113
2

You can simply loop over list1:

list1 = ['john','amal','joel','george']
list2 = [['john'],['jack','john','mary'],['howard','john'],['jude']]

res = {}
for w in list1: # if list1 contains duplicates use set(list1) instead
    # create an empty list for the name of list1 and extend it by all finds or
    # extend it by None
    res.setdefault(w,[]).extend( [(ind,ind2) for 
              ind,i in enumerate(list2) for ind2,y in enumerate(i) if w in y] or [None] )

# print all results by name
for k in res:
    print k, res[k]

# print all dict
print res

Output:

amal [None]
joel [None]
john [(0, 0), (1, 1), (2, 1)]
george [None]

{'amal': [None], 'joel': [None], 'john': [(0, 0), (1, 1), (2, 1)], 'george': [None]}

I am using a dict here, so you do not loose which one is where in the lists.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

You can use a nested list-comprehension:

[(i, j) for i, l in enumerate(list2) for j, s in enumerate(l) if s in list1]
#[(0, 0), (1, 1), (2, 1)]

And note that it is more efficient to convert list1 to a set first:

set1 = set(list1)
[(i, j) for i, l in enumerate(list2) for j, s in enumerate(l) if s in set1]
#[(0, 0), (1, 1), (2, 1)]
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
1

You could also create a dictionary of the occurrences:

list1 = ['john','amal','joel','george']
list2 = [['john'],['jack','john','mary'],['howard','john'],['jude']]
new_d = {i:[(c, d) for d, a in enumerate(list2) for c, g in enumerate(a) if g == i] for i in list1}

Output:

{'amal': [], 'joel': [], 'john': [(0, 0), (1, 1), (1, 2)], 'george': []}
Ajax1234
  • 69,937
  • 8
  • 61
  • 102