问题
I have a 2D list which I create like so:
Z1 = [[0 for x in range(3)] for y in range(4)]
I then proceed to populate this list, such that Z1
looks like this:
[[1, 2, 3], [4, 5, 6], [2, 3, 1], [2, 5, 1]]
I need to extract the unique 1x3
elements of Z1
, without regard to order:
Z2 = makeUnique(Z1) # The solution
The contents of Z2
should look like this:
[[4, 5, 6], [2, 5, 1]]
As you can see, I consider [1, 2, 3]
and [2, 3, 1]
to be duplicates because I don't care about the order.
Also note that single numeric values may appear more than once across elements (e.g. [2, 3, 1]
and [2, 5, 1]
); it's only when all three values appear together more than once (in the same or different order) that I consider them to be duplicates.
I have searched dozens of similar problems, but none of them seems to address my exact issue. I'm a complete Python beginner so I just need a push in the right direction.
I have already tried :
Z2= dict((x[0], x) for x in Z1).values()
Z2= set(i for j in Z2 for i in j)
But this does not produce the desired behaviour.
Thank you very much for your help!
Louis Vallance
回答1:
If the order of the elements inside the sublists does not matter, you could use the following:
from collections import Counter
z1 = [[1, 2, 3], [4, 5, 6], [2, 3, 1], [2, 5, 1]]
temp = Counter([tuple(sorted(x)) for x in z1])
z2 = [list(k) for k, v in temp.items() if v == 1]
print(z2) # [[4, 5, 6], [1, 2, 5]]
Some remarks:
- sorting makes lists
[1, 2, 3]
and[2, 3, 1]
from the example equal so they get grouped by theCounter
- casting to
tuple
converts thelist
s to something that is hashable and can therefore be used as adictionary
key. - the
Counter
creates adict
with thetuple
s created above as keys and a value equal to the number of times they appear in the originallist
- the final
list-comprehension
takes all those keys from theCounter dictionary
that have a count of 1.
If the order does matter you can use the following instead:
z1 = [[1, 2, 3], [4, 5, 6], [2, 3, 1], [2, 5, 1]]
def test(sublist, list_):
for sub in list_:
if all(x in sub for x in sublist):
return False
return True
z2 = [x for i, x in enumerate(z1) if test(x, z1[:i] + z1[i+1:])]
print(z2) # [[4, 5, 6], [2, 5, 1]]
来源:https://stackoverflow.com/questions/45592455/get-unique-elements-from-a-2d-list