11
>>> a= ('one', 'a')
>>> b = ('two', 'b')
>>> c = ('three', 'a')
>>> l = [a, b, c]
>>> l
[('one', 'a'), ('two', 'b'), ('three', 'a')]

How can I check for only the elements of this list with a unique second entry (column? item?), and then grab the first entry found on the list. Desired output is

>>> l
[('one', 'a'), ('two', 'b')]
1
  • Change ('three', 'c') to ('three', 'a') on the example on l output. Commented Jun 11, 2014 at 21:49

2 Answers 2

16

Use a set (if the second item is hash-able):

>>> lis = [('one', 'a'), ('two', 'b'), ('three', 'a')]
>>> seen = set()
>>> [item for item in lis if item[1] not in seen and not seen.add(item[1])]
[('one', 'a'), ('two', 'b')]

The above code is equivalent to:

>>> seen = set()
>>> ans = []
for item in lis:
    if item[1] not in seen:
        ans.append(item)
        seen.add(item[1])
...         
>>> ans
[('one', 'a'), ('two', 'b')]
Sign up to request clarification or add additional context in comments.

1 Comment

I finally understand this list comprehension. The "seen.add()" code always returns None, so saying "and not... always None" is not a condition to check at all, just a way to sneak a command into the list comprehension.
2

If order isn't important, you can use a dictionary:

d = {}

for t in reversed(l):
    d[t[1]] = t

print d.values()

Or more concisely:

{t[1]: t for t in reversed(l)}.values()

If you don't reverse the list, ('three', 'a') will overwrite ('one', 'a').

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.