Reputation: 7
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
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