Python Forum

Full Version: matching question
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hi all, 

I am building a personal project to match items from two different db tables. I got stuck so I started to break down my problems in little pieces. Here is one little piece regarding the matching:

participants = ('bob','bill','casey')
paid = ('bob', 'bill')

n = 0
for name in participants:
    lookup = paid[n]

    if name == lookup:
        match =+ 1
        n =+ 1
    else:
        n =+1
        if name == paid [n]:
           match =+ 1

print(match)
Output:
1
I would expect to get 2 matches. I have used pythontutor to visually step through the code, and I don't understand why the second name would not result in a match. Below I included a link to pythontutor of the step where I don't understand that a match is made between "bill" and "bill" https://goo.gl/npDnYf

Your help is appreciated!
You could use index():
https://www.tutorialspoint.com/python/list_index.htm

If not, you need two for-loops.
(Nov-21-2017, 11:11 AM)heiner55 Wrote: [ -> ]You could use index():
https://www.tutorialspoint.com/python/list_index.htm

If not, you need two for-loops.

Why do I need two for loops?

If I look at the code it says first that bob successfully matches. Then the "name" and the "lookup" are both changed to "bill" but this time the value for match is not increased by 1.?
Using list comprehensions or sets are common ways to solve this.
>>> participants = ('bob','bill','casey')
>>> paid = ('bob', 'bill')
>>> [x for x in participants if x in paid]
['bob', 'bill']
>>> len([x for x in participants if x in paid])
2

>>> list(set(participants).intersection(set(paid)))
['bob', 'bill']
>>> set(participants) & set(paid)
{'bob', 'bill'}
>>> 
You are using the wrong operator in your program:
Use "+=" instead of "=+".

participants = ('bob','bill','casey')
paid = ('bob', 'bill')

match = 0
for name in participants:
    for namepaid in paid:
        if name == namepaid:
            match += 1

print(match)
thanks guys for the quick help, much appreciated!

I have now replaced "participants" with the participant names from a database table:

import psycopg2 as p
import re

conn = p.connect ("dbname='participants_db' user='postgres' host= 'localhost'")
cur = conn.cursor()
cur.execute("select participant_name from participants")
names = cur.fetchall()

paid = ('Betinna', 'Amelia')


match = 0
for name in names:
    for namepaid in paid:
        if name == namepaid:
            match += 1

print(match)
Output:
0
If I print the names it looks likes this:
print(names)
Output:
[('Amelia',), ('Alden',), ('Bettina',), ('Billy Ray',), ('Bodean',), ('Bucephelus',), ('Buddy',), ('Casey',), ('Charlton',), ('Cleavon',), ('Cletus',), ('Clyde',), ('Cooter',), ('Daisy',), ('Doc',), ('Duke',), ('Elrod',), ('Georgina',), ('Homer',), ('Huck',), ('John Boy',), ('Percy',), ('Quinn',), ('Robbie',), ('Stella',)] Process finished with exit code 0
I have tried to strip the names first but that didn't change the result.

Any tips on how to the handle the data coming from the db before the match works?
names = [('Amelia',), ('Alden',), ('Bettina',), ('Billy Ray',)]
paid  = ('Bettina', 'Amelia')

match = 0
for name in names:
    for namepaid in paid:
        if name[0] == namepaid:
            match += 1

print(match)
Great, now the number of matches is correctly stated by matches two database tables. The next step is included "yes" in the column "participants_paid" of the participants table for all the participants that are matched. 

I have tried to include the following statement, but that gives an error. I probably have to adress the row of the match found in the table in order to specify where i have the insert the data.

import psycopg2 as p
import re

conn = p.connect ("dbname='participants_db' user='postgres' host= 'localhost'")
cur = conn.cursor()
cur.execute("select participant_name from participants")
names = cur.fetchall()

cur2 = conn.cursor()
cur2.execute("select paid_name from participants_paid")
paid = cur2.fetchall()


match = 0
for name in names:
    for namepaid in paid:
        if name[0] == namepaid[0]:
            match += 1
            cur.execute("insert into participants(participant_paid) values ('yes')")
            conn.commit()
print(match)
Error:
line 19, in <module>     cur.execute("insert into participants(participant_paid) values ('yes')") psycopg2.IntegrityError: null value in column "participant_id" violates not-null constraint DETAIL:  Failing row contains (null, null, null, yes).
Any ideas?
A slightly simpler way would be to just use the one for loop, as you only need to iterate through one list and check if each iteration is in the other list:
participants = ('bob', 'bill', 'casey')
paid = ('bob', 'bill')

match = 0
for name in participants:
    if name in paid:
        match += 1

print(match)
I would expect this to be quicker than using two loops also.
You are right. Using "in" is more pythonish.
Pages: 1 2