-1

List A:

[('Harry', 'X', 'A'),
 ('James', 'Y', 'G'),
 ('John', 'Z', 'D')]

List B:

[('Helen', '2', '(A; B)', '3'),
 ('Victor', '9', '(C; D; E)', '4'),
 ('Alan', '10', '(A)', '57'),
 ('Paul', '11', '(F; B)', '43'), 
 ('Sandra', '12', '(F)', '31')]

Basically I have to compare the third element (for x in listA -> x[2]) from list A and check if is there any list in list B that has the same element (for y in listB, x[2] == y[2]) but I'm just losing my mind with this.

My idea was to get the third element from each list in list B, put them into a new list, and then remove that ";" so I could access each element way more easily.

for x in listB:
    j = x[2]
    j = j.strip().split(', ')
    for k in j:
        FinalB.append(k)

FinalB = [(k[1:-1].split(";")) for k in FinalB]

Then I'd take the third element from each list of list A and compare them with the elements inside each list of FinalB: if there was a match, I'd get the index of the element in FinalB (the one that's matched), use that index to access his list in listB and get the first element of his list inside list B (basically, I have to know the names from the users inside each list that have the same 3rd element)

My code so far:

FinalB= []
DomainsList = []
for x in listA:
    j = x[2]
    j = j.strip().split(', ')
    for k in j:
        FinalB.append(k)

FinalB = [(k[1:-1].split(";")) for k in FinalB]

for y in listA:
    for z in FinalB:
        for k in z:
            if y[2] == k:
                m = FinalB.index(z)
                DomainsList.append([listA[m][0],listB[m][0]])
return DomainsList

Yes, this is not working (no error, I probably just did this in an absolute wrong way) and I can't figure out what and where I'm doing wrong.

Slifez
  • 53
  • 5
  • The parenthesis around each list are not balanced. Please update your lists so that they are valid syntax. – Ajax1234 Dec 11 '17 at 00:44
  • How is it "not working"? What does `FinalB` look like? The `j.strip().split(', ')`looks strange because there are no commas in `listA` - in fact, shouldn't that be `for x in list**B**:`? The first snippet uses `for x in listB:` but the second `for x in listA:`. – Ken Y-N Dec 11 '17 at 00:47
  • The expected result was a list of lists where each list consists in the name of each list that has matches. Imagine that only the first list in list A and list B has a match. Then the result should be this: FinalList = [('Harry', 'Helen')] – Slifez Dec 11 '17 at 00:49

2 Answers2

0

First, I think a better way to handle '(C; D; E)' is to change it to 'CDE', so the first loop becomes:

FinalB = [filter(str.isalpha, x[2]) for x in listB]

We take each string and keep only the alpha characters, so we end up with:

In [18]: FinalB
Out[18]: ['AB', 'CDE', 'A', 'FB', 'F']

This means we can use listA[x][2] in FinalB[y] to test if we have a match:

for y in listA:
    for z in FinalB:
        if y[2] in z:
            DomainsList.append([y[0], listB[FinalB.index(z)][0]])

I had to tweak the arguments to the append() to pick the right elements, so we end up with:

In [17]: DomainsList
Out[17]: [['Harry', 'Helen'], ['Harry', 'Alan'], ['John', 'Victor']]

Usefully, if instead of '(C; D; E)' you have '(foo; bar; baz)', then with just one tweak the code can work for that too:

import re
FinalB = [filter(None, re.split("[; \(\)]+", x[2])) for x in listB]

The remaining code works as before.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
0

It will always help to start a question with context and details. The python version could also come into play.

The data structure you have given for us to work with is very questionable - especially the third element in each of the tuples in listB...why have a string element and then define it like this '(C; D; E)' ??

Even though I don't understand where you are coming from with this or what this is meant to achieve,no context provided in post, this code should get you there.

It will give you a list of tupples ( listC ), with each tuple having two elements. Element one having the name from listA and element 2 having the name from listB where they have a match as described in post. NOTE: at the moment the match is simply done with a find, which will work perfectly with the provided details, however you may need to change this to be suitable for your needs if you could have data that would cause false positives or if you want to ignore case.

listA = [('Harry', 'X', 'A'), ('James', 'Y', 'G'), ('John', 'Z', 'D')]

listB = [('Helen', '2', '(A; B)', '3'), 
         ('Victor', '9', '(C; D; E)', '4'), 
         ('Alan', '10', '(A)', '57'), 
         ('Paul', '11', '(F; B)', '43'), 
         ('Sandra', '12', '(F)', '31')]

listC = []

for a in listA:
  for b in listB:
     if b[2].find(a[2]) != -1:
       listC.append((a[0], b[0]))

print(listC)

This gives you. [('Harry', 'Helen'), ('Harry', 'Alan'), ('John', 'Victor')]

Rohan
  • 578
  • 8
  • 12