Search for tuple in an array

Asked

Viewed 288 times

4

I have the following vectors:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]

b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['FI', 'SE', 0.054]]

I need to go through the vector to and locate it on the vector b.

My exit has to return:

c = ['FI', 'SE', 0.054]

How can I do that?

Grateful for the help.

  • Will the two lists always have the same amount of sublists? If a has a has 5 sublists then b also has? Or it may be different?

  • They can have different sizes @Miguel.

  • How is the search? Search for (FI, SE) that’s it?

  • Exactly @Miguel! I look for (FI, SE), but the return will be ['FI', 'SE', 0.054], as in b.

3 answers

2

If, instead of a list of lists, you can upload b as a dictionary (or transform b in a dictionary bd, as I did in the example below) the code can become more intuitive, just one bd.get to locate the required value. Ex.:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]
b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['FI', 'SE', 0.054]]

bd = dict(((x, y), z) for x, y, z in b)
print(bd)
# saída: {('FI', 'SE'): 0.054, ('NL', 'BE'): 0, ('NL', 'DE'): 0, ('NL', 'DK'): 0}

c = [(i, bd.get(i)) for i in a if i in bd]    
print(c)
# saída: [(('FI', 'SE'), 0.054)]
  • 1

    @Miguel, actually this code is much faster than what you proposed, even adding the conversion time of b to a dictionary, because the in in dicts is O(1), while in lists and tuples is O(n).

  • With small datasets the difference is derisory (milliseconds in favor of the A method, without a dictionary), but with large datasets the difference is orders of magnitude in favor of the dictionary method: https://repl.it/WorthlessAustereRegression

  • 1

    @Miguel It is part of learning, for everyone. : ) I didn’t need to delete the comments, they might be useful for other people who had the same doubt about the approaches.

  • It was already very messy here

2


You can try it like this:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]
b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['FI', 'SE', 0.054]]

search1, search2 = ('FI', 'SE')
for val1, val2, val3 in b:
  if((val1, val2) == (search1, search2)):
    print(val1, val2, val3) # FI SE 0.054
    break
else: # caso nao haja break e porque nao foi encontrado
  print('não foi encontrado')

DEMONSTRATION

If you want to locate all elements of a in b, can:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]
b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['DE', 'PL', 0], ['FI', 'SE', 0.054]]

founds = []
for val1, val2, val3 in b:
  if((val1, val2) in a):
   founds.append([val1, val2, val3])
print(founds) # [['DE', 'PL', 0], ['FI', 'SE', 0.054]]

DEMONSTRATION

Or:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]
b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['DE', 'PL', 0], ['FI', 'SE', 0.054]]

founds = [[v[0], v[1], v[2]] for v in b if (v[0], v[1]) in a]
print(founds) # [['DE', 'PL', 0], ['FI', 'SE', 0.054]]
  • 1

    Thank you @Miguel. Works perfectly!

  • You’re welcome @Danilo

1

See if that helps you:

a = [('FI', 'SE'), ('SE', 'DK'), ('DK', 'DE'), ('DE', 'PL'), ('PL', 'BY')]

b = [['NL', 'DK', 0], ['NL', 'DE', 0], ['NL', 'BE', 0], ['FI', 'SE', 0.054]]

result = []
for x in a:
    for z in b:
        if len(list(set(x) - set(z))) == 0:
            result.append(z)

print(result) # [['FI', 'SE', 0.054]]

In the example I go through the 2 lists and check the difference between the elements to get the result you expect, and then add to the list result.

NOTE: I’m starting my studies in python, so sorry about anything.

  • 1

    Thank you @Juniornunes your solution also suits me! (+1)

  • 1

    This approach has the problem of considering ('FI', 'SE') == ('SE', 'FI'), due to the use of sets. In addition, the conversion + operation with sets to each item makes the code super slow (2 minutes to compare two lists with 10,000 items each).

  • Thanks for the @hdiogenes remark!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.