Using an Index to Get an Item

Using an index to get an item

What you show, ('A','B','C','D','E'), is not a list, it's a tuple (the round parentheses instead of square brackets show that). Nevertheless, whether it to index a list or a tuple (for getting one item at an index), in either case you append the index in square brackets.

So:

thetuple = ('A','B','C','D','E')
print thetuple[0]

prints A, and so forth.

Tuples (differently from lists) are immutable, so you couldn't assign to thetuple[0] etc (as you could assign to an indexing of a list). However you can definitely just access ("get") the item by indexing in either case.

Accessing the index in 'for' loops

Use the built-in function enumerate():

for idx, x in enumerate(xs):
print(idx, x)

It is non-pythonic to manually index via for i in range(len(xs)): x = xs[i] or manually manage an additional state variable.

Check out PEP 279 for more.

Cannot get an index of a list item

The problem is that the type of variable pick is a list.

You need to pass an int to the index command:

In [314]: list1.index(pick[0])
Out[314]: 4

Finding the index of an item in a list

>>> ["foo", "bar", "baz"].index("bar")
1

See the documentation for the built-in .index() method of the list:

list.index(x[, start[, end]])

Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item.

The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

Caveats

Linear time-complexity in list length

An index call checks every element of the list in order, until it finds a match. If the list is long, and if there is no guarantee that the value will be near the beginning, this can slow down the code.

This problem can only be completely avoided by using a different data structure. However, if the element is known to be within a certain part of the list, the start and end parameters can be used to narrow the search.

For example:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

The second call is orders of magnitude faster, because it only has to search through 10 elements, rather than all 1 million.

Only the index of the first match is returned

A call to index searches through the list in order until it finds a match, and stops there. If there could be more than one occurrence of the value, and all indices are needed, index cannot solve the problem:

>>> [1, 1].index(1) # the `1` index is not found.
0

Instead, use a list comprehension or generator expression to do the search, with enumerate to get indices:

>>> # A list comprehension gives a list of indices directly:
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> # A generator comprehension gives us an iterable object...
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> # which can be used in a `for` loop, or manually iterated with `next`:
>>> next(g)
0
>>> next(g)
2

The list comprehension and generator expression techniques still work if there is only one match, and are more generalizable.

Raises an exception if there is no match

As noted in the documentation above, using .index will raise an exception if the searched-for value is not in the list:

>>> [1, 1].index(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

If this is a concern, either explicitly check first using item in my_list, or handle the exception with try/except as appropriate.

The explicit check is simple and readable, but it must iterate the list a second time. See What is the EAFP principle in Python? for more guidance on this choice.

How to get Index of an Item in ICollectionT

If you want to use an indexed collection then you should use IList<T>, not ICollection<T>. An ICollection<T> is something that you can enumerate, add and remove items for, and get the count of, that's all. An IList<T> is a collection in which the items are in a specified order, and can be accessed based on their position in the list.

Because an ICollection<T> doesn't necessarily represent an ordered collection, you cannot get a meaningful "index" of an item. Items don't necessarily have a position.

How do I index f.items()?

You can create a list and then index.

item = list(f.items())[1]

Lists are created often in python and this operation is relatively inexpensive. If your dictionary is large, you can create an iterator and take its second value.

i = iter(f.items())
next(i)
item = next(i)

But the dict would need to be rather large to make this the better option.

Picking out items from a python list which have specific indexes

[main_list[x] for x in indexes]

This will return a list of the objects, using a list comprehension.



Related Topics



Leave a reply



Submit