[Tutor] single key ordered sequence

Kent Johnson kent37 at tds.net
Thu Jan 15 16:32:27 CET 2009


On Thu, Jan 15, 2009 at 6:48 AM, spir <denis.spir at free.fr> wrote:

> I have a list of tuples element, in which the first item is a kind of key. I need a target list
> with only one tuple per key. But the order must be kept -- so that I cannot use a temp dictionary.
> Additionally, in this case the chosen element for a repeted key is the last one occurring in
> source list.
>
> How would you do that?

In [1]: items =
[(1,'a'),(1,'b'),(2,'a'),(3,'a'),(3,'b'),(4,'a'),(5,'a'),(5,'b'),(5,'c')]
In [2]: seen = set()
In [3]: newItems = []

In [5]: for item in reversed(items):
   ...:     if item[0] not in seen:
   ...:         seen.add(item[0])
   ...:         newItems.append(item)

In [6]: newItems
Out[6]: [(5, 'c'), (4, 'a'), (3, 'b'), (2, 'a'), (1, 'b')]

In [7]: newItems.reverse()

In [8]: newItems
Out[8]: [(1, 'b'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'c')]

Or, with a somewhat hacky list comp:

In [9]: seen = set()

In [10]: [ item for item in reversed(items) if item[0] not in seen and
not seen.add(item[0]) ]

> Also, how to practically walk in reverse order in a list without copying it (e.g. items[::-1]),
> especially if i need both indexes and items (couldn't find with enumerate()).

See use of reversed() above. You can combine it with enumerate():

In [13]: list(enumerate(reversed(items)))
Out[13]:
[(0, (5, 'c')),
 (1, (5, 'b')),
 (2, (5, 'a')),
 (3, (4, 'a')),
 (4, (3, 'b')),
 (5, (3, 'a')),
 (6, (2, 'a')),
 (7, (1, 'b')),
 (8, (1, 'a'))]

In [16]: list(reversed(list(enumerate(items))))
Out[16]:
[(8, (5, 'c')),
 (7, (5, 'b')),
 (6, (5, 'a')),
 (5, (4, 'a')),
 (4, (3, 'b')),
 (3, (3, 'a')),
 (2, (2, 'a')),
 (1, (1, 'b')),
 (0, (1, 'a'))]

Kent


More information about the Tutor mailing list