Python: compare list and list of tuples

I have a list as shown below:

z = [('Anna Smith', 'IN1'), ('John', 'IN2'), ('Matt Andrew', 'IN3'), ('Smith', 'IN4')]

      

And one more list:

c = ['Anna Smith', 'John', 'Anna', 'Smith']

      

I need the following output:

o = ['Anna Smith|IN1', 'John|IN2', 'Smith|IN4']

      

I have tried the below code:

for s, s_inc in z:
     for word in c:
          if word.lower() in s.lower():
                o.append("%s|%s"%(word, s_inc))

      

But the above gives me the output:

o = ['Anna Smith|IN1', 'Anna|IN1', 'Smith|IN1', 'John|IN2', 'Smith|IN4']

      

How do I get what I want?

+3


source to share


5 answers


List comprehension is an elegant technique for this type of filtering / list problems.

Understanding has three parts:

-First result is plotted in + '|' + b



... Second, a and b are assigned to the first and second element in every 2-tuple in the list z

... Third, we filter the condition that a must be a member of the list c

print [a+'|'+b for a,b in z if a in c]

# Prints ['Anna Smith|IN1', 'John|IN2', 'Smith|IN4']

      

+2


source


From your examples, it sounds like you are looking for an exact match, so use ==

instead in

:

for s, s_inc in z:
     for word in c:
          if word == s:
                o.append("%s|%s"%(word, s_inc))

      

Or, in short, as a single list comprehension:



o = ["%s|%s"%(s, s_inc) for s, s_inc in z if s in c]

      

After that o

there is['Anna Smith|IN1', 'John|IN2', 'Smith|IN4']

0


source


Try the following:

z = [('Anna Smith', 'IN1'), ('John', 'IN2'), ('Matt Andrew', 'IN3'), ('Smith', 'IN4')]
c = set(['Anna Smith', 'John', 'Anna', 'Smith'])

o = [
    '|'.join([name, code]) for name, code in z if name in c   
]

      

0


source


I would make c

a quick test suite with constant time:

c_set = {w.lower() for w in c}

      

I am antialiasing the words so that it is easy to check membership in a case insensitive manner.

Then just use:

for s, s_inc in z:
    if s.lower() in c_set:
        o.append('|'.join([s, s_inc]))

      

or even:

o = ['|'.join([s, s_inc]) for s, s_inc in z if s.lower() in c_set]

      

to create an entire combo box.

Demo:

>>> z = [('Anna Smith', 'IN1'), ('John', 'IN2'), ('Matt Andrew', 'IN3'), ('Smith', 'IN4')]
>>> c = ['Anna Smith', 'John', 'Anna', 'Smith']
>>> c_set = {w.lower() for w in c}
>>> ['|'.join([s, s_inc]) for s, s_inc in z if s.lower() in c_set]
['Anna Smith|IN1', 'John|IN2', 'Smith|IN4']

      

0


source


>>> z = [('Anna Smith', 'IN1'), ('John', 'IN2'), ('Matt Andrew', 'IN3'), ('Smith', 'IN4')]
>>> c = ['Anna Smith', 'John', 'Anna', 'Smith']
>>> ['|'.join([i,x[1]]) for x in z for i in c if x[0]==i]
['Anna Smith|IN1', 'John|IN2', 'Smith|IN4']

      

0


source







All Articles