Itemgetter Except Columns

665 views python
4

Is there a way to get the complement of a set of columns using itemgetter?

For example, you can get the first, third, and fifth elements of a list using

from operator import itemgetter
f = itemgetter(0, 2, 4)
f(['a', 'b', 'c', 'd', 'e']) ## == ('a', 'c', 'e')

Is there a (simple) way to get all of the elements except for the first, third and fifth?

answered question

For an arbitrary length input? No.

3 Answers

4

You could use a set to get the difference:

>>> from operator import itemgetter

>>> obj = ['a', 'b', 'c', 'd', 'e']
>>> c = {1, 3, 5}  # Get everything but these
>>> get = set(range(len(obj))).difference(c)
>>> f = itemgetter(*get)
>>> f(obj)
('a', 'c', 'e')

where set(range(len(obj))) is all the indices, i.e. {0, 1, 2, 3, 4}.

posted this
10

I'd write it like this:

>>> from operator import itemgetter
>>> items = ['a', 'b', 'c', 'd', 'e']
>>> exclude = {0, 2, 4}
>>> get = [x for x in range(len(items)) if x not in exclude]
>>> 
>>> itemgetter(*get)(items)
>>> ('b', 'd')

posted this
2

No, there is no way to spell everything but these indices in Python.

You can use slices to get everything after the 5th element:

itemgetter(1, 3, slice(5, None))

but then you'd get a separate list for the slice component:

>>> itemgetter(1, 3, slice(5, None))(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
('b', 'd', ['f', 'g'])

and an error if the input sequence is not at least 4 elements long:

>>> itemgetter(1, 3, slice(5, None))(['a', 'b', 'c'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Rather than use itemgetter(), just use a set and a list comprehension:

def excludedgetter(indices):
    excluded = set(indices)
    return lambda seq: [v for i, v in enumerate(seq) if i not in excluded]

posted this

Have an answer?

JD

Please login first before posting an answer.