Home > Software design >  Deleting coordinates with same x value
Deleting coordinates with same x value

Time:10-18

I'm trying to 'sort' a list by removing every multiples coordinates with same X (or Y) values. As example, I've the following list :

[(682, 547), (682, 548), (638, 657), (638, 658)]

And I would like to have :

[(682, 547), (638, 657)]

Any idea on how to do this ?

CodePudding user response:

Use a set to keep track of the already seeing X coordinates:

seen = set()
data = [(682, 547), (682, 548), (638, 657), (638, 658)]

result = []
for d in data:
    if d[0] not in seen:
        seen.add(d[0])
        result.append(d)
print(result)

Output

[(682, 547), (638, 657)]

Alternative:

CodePudding user response:

It was an interesting question, so I made it up. It's a lot of code, but I hope it helps.

class ListClass(list):
    def __init__(self, *children):
        self._children = []
        self._minvalues = [None, None]
        self._maxvalues = [None, None]
        self.extend(children)
    def append(self, value):
        if not isinstance(value, tuple):
            raise ValueError(value)
        self._update(value)
        self._children.append(value)
    def extend(self, values):
        for value in values:
            self.append(value)
    def _update(self, value):
        for i in range(len(value)):
            if not self._minvalues[i] or self._minvalues[i] > value[i]:
                self._minvalues[i] = value[i]
            if not self._maxvalues[i] or self._maxvalues[i] < value[i]:
                self._maxvalues[i] = value[i]
    def __repr__(self):
        """
        >>> a = ListClass((1, 2), (2, 4), )
        >>> a
        [(1, 2), (2, 4)]
        """
        return str(self._children)
    def __len__(self):
        """
        >>> a = ListClass((1, 2), (2, 4), )
        >>> a.append((6,3))
        >>> len(a)
        3
        """
        return len(self._children)
    def __setitem__(self, key, value):
        raise NotImplementedError
    def __getitem__(self, key):
        return self._children[key]
    def shrink(self):
        """
        >>> a = ListClass((1, 2), (2, 4), (3, 1), )
        >>> a.shrink()
        [(1, 1), (3, 4)]
        >>> a = ListClass((682, 547), (682, 548), (638, 657), (638, 658), )
        >>> a.shrink()
        [(638, 547), (682, 658)]
        """
        return [tuple(self._minvalues), tuple(self._maxvalues)]

if __name__ == '__main__':
    import doctest
    doctest.testmod()

CodePudding user response:

You could create a generator with Dani Mesejo's approach using a set:

from operator import itemgetter

data = [(682, 547), (682, 548), (638, 657), (638, 658)]


def first(list, key=lambda record: record):
    
    visited = set()
    
    for record in list:
        index = key(record)
        if index not in visited:
            yield record
            visited.add(index)


for record in first(data, key=itemgetter(0)):
    print(record)

# (682, 547)
# (638, 657)

# or in case you just need a list
result = list(first(data, key=itemgetter(0))
print(result)

# [(682, 547), (638, 657)]
  • Related