dlang17
dlang17

Reputation: 7

Creating list checker in Python. Compares lists and provides difference between them. Struggling with tail end of script

I am writing a short script that is suppose to look at a master list and a (for lack of better term) slave list, and output inconsistencies in the slave list when compared to the master list. I am very much a novice when it comes to coding..... Any insight would be much appreciated.

The data I'm trying to sort are in text files. Look something like the following:

12345678-Bananas

23456789-Apples

12345678-StarWars

23456789-RedBall

11223344-RedRover

22334455-Rabbit

I sort the data into lists (I think) using the follow bit of code:

    filename = utils.SelectOpenFile(0, "Text file (*.txt)")
    print (filename[0])
    if not filename[0]:
        return          
    text_file = open(filename[0], "r")  
    Part_List = text_file.read( ).splitlines( )

    PN_List = [ ]
    index = 0
    for line in Part_List:
        PN_List.append (Part_List[index][:8])
        PN_List[index] = PN_List[index].lower( )
        index += 1

    List1 = sorted(list(Counter(PN_List).items( )))

Which nets me:

List1 = [('12345678',2),('23456789',2),('11223344',1),('22334455',1)]

then compare it to another list that will either be identical or slightly different, like so:

List2 = [('12345678',3),('23456789',1),('11223344',1)]

I'm trying to see if List2 matches the "master" List1. What I would like as an output would be:

List3 = [('12345678',-1),('23456789',1),('22334455',1)]

So far have tried the following:

    for x in List2:
        if x[0] in List1:
            if x[1] < x[1] in List1:
                print ("Too Few Parts")
            elif x[1] > x[1] in List1:
                print ("Too Many Parts")
            else:
                print ("Perfecto")
        else:
            print ("Extra Part")
    for y in List1:
        if y[0] in List2:
            return
        else:
            print ("Missing Part")

open to better solutions

Upvotes: 0

Views: 86

Answers (1)

BoarGules
BoarGules

Reputation: 16951

I take it that

List1 = [('12345678',2),('23456789',2),('11223344',1),('22334455',1)]

represents a set of part numbers and a quantity on hand. You are finding this difficult because your data structure doesn't match the problem you are trying to solve. Convert the master list to a dictionary:

>>> master = dict(List1)
>>> master
{'12345678': 2, '23456789': 2, '11223344': 1, '22334455': 1}

and do the same with the slave list:

>>> slave = dict(List2)

Now you will have a much easier time of matching up the part numbers.

>>> result = master.copy()
>>> for k,v in slave.items():
        if k in master:
            result[k] -= v
        else:
            print (f"Missing part {k}")

Now convert the resulting dictionary back to a list of (part-number, quantity) tuples. You could just do List3 = list(result.items()) but it appears you want to drop a part number from the master list if the quantity goes to zero.

>>> List3 = [(k,v) for (k,v) in result.items() if v != 0]
>>> List3
[('12345678', -1), ('23456789', 1), ('22334455', 1)]

You can use Counter for this too, but first you need to do it the hard way so that you understand what Counter is doing. The solution is identical. The only difference is that Counter does the subtracting for you in one function call.

>>> from collections import Counter
>>> c1 = Counter(dict(List1))
>>> c2 = Counter(dict(List2))
>>> c3=c1.copy()
>>> c3.subtract(c2)
>>> c3
Counter({'23456789': 1, '22334455': 1, '11223344': 0, '12345678': -1})
>>> List3 = [(k,v) for (k,v) in c3.items() if v != 0]
>>> List3
[('12345678', -1), ('23456789', 1), ('22334455', 1)]

Upvotes: 1

Related Questions