-3

How to index a list using a variable?

Using the below example, how can a and b be used to return the equivalent of a[1]?

>>> a = range(5)
>>> b = [1]

>>> a[1]
1

>>> a(b)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-46-ec02cd35061d> in <module>()
      5 a[1]
      6 
----> 7 a(b)

TypeError: 'range' object is not callable

>>> (a)b
  File "<ipython-input-51-0a1106519cc7>", line 1
(a)b
   ^
SyntaxError: invalid syntax
Greg
  • 8,175
  • 16
  • 72
  • 125
  • Can you give examples of other values of `b` you'd like to see work? Is your goal to make the *index* variable or the *operation*? – Martijn Pieters Aug 29 '17 at 07:01
  • Or, if you did consciously meant `b` to be a list, what should happen if there are 0 elements in that list? Or more than one? – Martijn Pieters Aug 29 '17 at 07:02

1 Answers1

1

b is a list, not an integer. If b was set to 1 you can just use that to index:

b = 1
a[b]

If you were looking to store the operation as a variable (not just the index, but that you are indexing in the first place), use functions or helper objects from the operator module.

For example, you can store a operator.itemgetter() object:

from operator import itemgetter

b = itemgetter(1)  # ...[1]
b(a)               # apply to a
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Answering a question after it's closed is cheating :P – TerryA Aug 29 '17 at 06:58
  • @TerryA: I wrote my answer before it was closed. And there is a grace period that allows submission of answers for up to 4 hours. – Martijn Pieters Aug 29 '17 at 06:59
  • @TerryA: besides, I'm not sure this is a duplicate. The OP could be asking how to store the *operation*, e.g. they want to swap that out for attribute access, or a method call, etc. – Martijn Pieters Aug 29 '17 at 07:00
  • @TerryA There is absolutely no reason to close this question as it is not a duplicate. The question is not about how to index using an interger but a list. Sure conversion might be simple, the point is, perhaps there is a special method or another approach which is less well known. – Greg Aug 29 '17 at 07:00
  • @Dave Use the `operator.itemgetter` approach: `operator.itemgetter(*b)(a)`, where `b` is the list of indexes – TerryA Aug 29 '17 at 07:01
  • @Dave: you need to clarify your question then. Because it looked to me that you were trying to echo the `object[...]` indexing syntax. What should happen when `b` is set to `[42, 81]`? – Martijn Pieters Aug 29 '17 at 07:02
  • @MartijnPieters They do specifically say indexing though :/ – TerryA Aug 29 '17 at 07:02
  • @TerryA: yes, but indexing is one possible operation. When someone sees the `object[...]` syntax and tried to separate the `[...]` part, they could see that as the operation, and expect the same to work for `object.attribute` (trying to store `.attribute` in a variable), etc. – Martijn Pieters Aug 29 '17 at 07:04
  • @MartijnPieters My intention was to understand how pandas perform their indexing (e.g. `df['col']` and `df[['col1','col2']]` and whether or not a `['col']` can be used as a user input in a function. – Greg Aug 29 '17 at 07:05
  • 2
    @Dave: That's *two* questions. Pandas have a custom `__getitem__` implementation that accepts tuples (Python passes in the tuple `('col1', 'col2')`); that question has been answered before, usually for numpy however. – Martijn Pieters Aug 29 '17 at 07:07
  • @Dave: `['col']` creates a list object, always. Any object can be passed in as user input in a function. Neither question has anything to do with your current question. – Martijn Pieters Aug 29 '17 at 07:07
  • @MartijnPieters Let `b` be a user input which needs to be a list due to another function path, the question was to understand if it was possible to use this list or if it needs to be indexed with `[0]`. Your solution is much better though as it allows for multiple elements to be accessed. Thank you – Greg Aug 29 '17 at 07:11
  • So, does that mean this isn't a dupe? Must it be reopened? – cs95 Aug 29 '17 at 07:14
  • @cᴏʟᴅsᴘᴇᴇᴅ: at which point I'll close it as 'unclear'. – Martijn Pieters Aug 29 '17 at 07:15
  • @cᴏʟᴅsᴘᴇᴇᴅ Martin's solution is in the duplicate question, is it not? – TerryA Aug 29 '17 at 07:15
  • @cᴏʟᴅsᴘᴇᴇᴅ It's not a dupe. The question was about how to use a list object to index another list object. – Greg Aug 29 '17 at 07:15
  • @MartijnPieters I am happy for you to change the closing tag if you wish – TerryA Aug 29 '17 at 07:16
  • 1
    @Dave If you're talking about pandas then you'd be looking for [`__getitem__`](https://github.com/margaret/pandas/blob/d13082430513a0ebcb61f0c4ad79eebeab27194f/pandas/core/indexing.py#L108). – cs95 Aug 29 '17 at 07:16
  • @TerryA Can this question be reopened? The question was not a duplicate as it was about indexing a list using a list. I've been on SO for over 2 years and this is by far the worst treatment I've received (as a result of misjudgement). Such treatment can be quite discouraging for newer users and it's why SO is getting a bad reputation for community unfriendliness. – Greg Aug 29 '17 at 07:32
  • 1
    @Dave Misread your sentence. I will re-open – TerryA Aug 29 '17 at 07:45