If i have a list in python say
thing = [[20,0,1],[20,0,2],[20,1,1],[20,0],[30,1,1]]
I would want to have a resulting list
thing = [[20,1,1],[20,0,2],[30,1,1]]
That is if the first element is the same, remove duplicates and give priority to the number 1 in the second element. Lastly the 3rd element must also be unique to the first element.
In this previous question we solved a complicated method where for a transaction it details a purchased unit. I want to output other units in that course. If two transactions exist that relate to two units in one course it will display them a duplicate (or times each subsequent unit).
The aim of this question it to ensure that this duplication is stopped. Because of the complication of this solution it has resulted in a series of question. Thanks for everyone that has helped so far.
I am not sure you would like this, but it works with your example:
[list(i) + j for i, j in dict([(tuple(x[:2]), x[2:]) for x in sorted(thing, key=lambda x:len(x))]).items()]
EDIT:
Here a bit more detailed (note that it fits better to your description of the problem, sorting ONLY by the length of each sublist, may not be the best solution):
thing = [[20,0,1],[20,0,2],[20,1,1],[20,0],[30,1,1]]
dico = {}
for x in thing:
if not tuple(x[:2]) in dico:
dico[tuple(x[:2])] = x[2:]
continue
if tuple(x[:2])[1] < x[1]:
dico[tuple(x[:2])] = x[2:]
new_thing = []
for i, j in dico.items():
new_thing.append(list(i) + j)
You might want to try using the unique_everseen function from the itertools recipes.
As a first step, here is a solution excluding [20, 0]:
from itertools import filterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
thing = [[20,0,1],[20,0,2],[20,1,1],[30,1,1]]
thing.sort(key=lambda x: 0 if x[1] == 1 else 1)
print(list(unique_everseen(thing, key=lambda x: (x[0], x[2]))))
Output:
[[20, 1, 1], [30, 1, 1], [20, 0, 2]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With