I have a list of instances from the same class, and I want to make my list distinct based on a property in the class. What is the most pythonic way to achieve this?
Here is some sample code:
#!/usr/bin/python
#-*- coding:utf-8 -*-
class MyClass(object):
def __init__(self, classId, tag):
self.classId = classId
self.tag = tag
myList = []
myInstance1 = MyClass(1, "ABC")
myInstance2 = MyClass(2, "DEF")
myInstance3 = MyClass(3, "DEF")
myList.append(myInstance1)
myList.append(myInstance3) # note that the order is changed deliberately
myList.append(myInstance2)
If I want to sort my list now based on one of the properties in MyClass, I usually just sort it by key, and set the key using a lambda expression - like this:
myList.sort(key=lambda x: x.classId)
for x in myList:
print x.classId
$ python ./test.py
1
2
3
Is it possible to use a similar method (lambda, map or similar) to make the list distinct based on the "tag" property? Also, if this is possible, is it the most "pythonic" way to make a list distinct based on a property of a class in that list?
I have already tried searching both SO and Google for topics on this matter, but all the results I found dealt with simple lists that only contained a numeric value and not a custom object..
Using Python's import numpy, the unique elements in the array are also obtained. In the first step convert the list to x=numpy. array(list) and then use numpy. unique(x) function to get the unique values from the list.
You can use the combination of the SUM and COUNTIF functions to count unique values in Excel. The syntax for this combined formula is = SUM(IF(1/COUNTIF(data, data)=1,1,0)). Here the COUNTIF formula counts the number of times each value in the range appears.
You can use python dict comprehension
{x.tag: x for x in myList}.values()
For your example:
>>> class MyClass(object):
... def __init__(self, classId, tag):
... self.classId = classId
... self.tag = tag
...
>>> myList = [MyClass(1, "ABC"), MyClass(2, "DEF"), MyClass(3, "DEF")]
>>> uniqList = {x.tag: x for x in myList}.values()
>>> print [x.classId for x in uniqList]
[1, 3]
Assuming the property you wish to key on is immutable, you can use a dict:
d = {}
for x in xs:
d[x.tag] = x
Now d
will contain a single x
per tag
value; you can use d.values()
or d.itervalues()
to get at the xs
.
NB. here last matching item wins; to have the first one win, iterate in reverse.
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