42

Is there a "pythonic" way of getting only certain values from a list, similar to this perl code:

my ($one,$four,$ten) = line.split(/,/)[1,4,10]
1
  • 1
    Btw, that isn't valid Perl. Rather: my (...) = (split /,/, $line)[1,4,10]; Commented Nov 21, 2022 at 9:09

8 Answers 8

45

Using a list comprehension

line = '0,1,2,3,4,5,6,7,8,9,10'
lst = line.split(',')
one, four, ten = [lst[i] for i in [1,4,10]]
Sign up to request clarification or add additional context in comments.

Comments

27

I think you are looking for operator.itemgetter:

import operator
line=','.join(map(str,range(11)))
print(line)
# 0,1,2,3,4,5,6,7,8,9,10
alist=line.split(',')
print(alist)
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
one,four,ten=operator.itemgetter(1,4,10)(alist)
print(one,four,ten)
# ('1', '4', '10')

3 Comments

Not really. If you take out the demonstrative code it can look like this: one,four,ten=operator.itemgetter(1,4,10)(line.split(','))
You’re a lifesaver, thanks! If timeit is right, this should reduce the runtime of a codesnippet we examined today from 9 hours to a few seconds.
Unnecessary to use a library when it can be achieved with list comprehension, see @has2k1 answer.
9
lst = line.split(',')
one, four, ten = lst[1], lst[4], lst[10]

4 Comments

I think you misunderstood the question
@Idan: may be I have, am I not supposed to get 2nd, 5th and 11th elements of the new list?
@Idan K: There's no requirement that the "Pythonic" version be a single expression like the Perl version.
Although itemgetter might satisfy the OP's request in one line, I have to agree with Lennart here that this solution is most readable and easily understandable
5

Try operator.itemgetter (available in python 2.4 or newer):

Return a callable object that fetches item from its operand using the operand’s ____getitem____() method. If multiple items are specified, returns a tuple of lookup values.

>>> from operator import itemgetter
>>> line = ','.join(map(str, range(11)))
>>> line
'0,1,2,3,4,5,6,7,8,9,10'
>>> a, b, c = itemgetter(1, 4, 10)(line.split(','))
>>> a, b, c
('1', '4', '10')

Condensed:

>>> # my ($one,$four,$ten) = line.split(/,/)[1,4,10]
>>> from operator import itemgetter
>>> (one, four, ten) = itemgetter(1, 4, 10)(line.split(','))

1 Comment

You’re a lifesaver, thanks! If timeit is right, this should reduce the runtime of a codesnippet we examined today from 9 hours to a few seconds.
3

How about this:

index = [1, 0, 0, 1, 0]
x = [1, 2, 3, 4, 5]
[i for j, i in enumerate(x) if index[j] == 1]
#[1, 4]

Comments

1

Yes:

data = line.split(',')
one, four, ten = data[1], data[4], data[10]

You can also use itemgetter, but I prefer the code above, it's clearer, and clarity == good code.

Comments

0

Alternatively, if you had a Numpy array instead of a list, you could do womething like:

from numpy import array

# Assuming line = "0,1,2,3,4,5,6,7,8,9,10"
line_array = array(line.split(","))

one, four, ten = line_array[[1,4,10]]

The trick here is that you can pass a list (or a Numpy array) as array indices.

EDIT : I first thought it would also work with tuples, but it's a bit more complicated. I suggest to stick with lists or arrays.

Comments

0

Using pandas:

import pandas as pd
line = "0,1,2,3,4,5,6,7,8,9,10"
line_series = pd.Series(line.split(','))
one, four, ten = line_series[[1,4,10]]

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.