Colon (:) in Python List Index

Colon (:) in Python list index

: is the delimiter of the slice syntax to 'slice out' sub-parts in sequences , [start:end]

[1:5] is equivalent to "from 1 to 5" (5 not included)
[1:] is equivalent to "1 to end"
[len(a):] is equivalent to "from length of a to end"

Watch https://youtu.be/tKTZoB2Vjuk?t=41m40s at around 40:00 he starts explaining that.

Works with tuples and strings, too.

What is :: (double colon) in Python when subscripting sequences?

it means 'nothing for the first argument, nothing for the second, and jump by three'. It gets every third item of the sequence sliced.
Extended slices is what you want. New in Python 2.3

How can I use colon (:) in variable

You want a slice() object:

index = slice(0, 2)
print(somelist[index])

slice() models the start, stop and stride values you can specify in the [start:stop:stride] subscription syntax, as an object.

From the documentation:

Return a slice object representing the set of indices specified by range(start, stop, step). The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default).

Under the covers, Python actually translates subscriptions to a slice() object when calling custom __getitem__ methods:

>>> class Foo(object):
... def __getitem__(self, item):
... return item
...
>>> Foo()[42:81:7]
slice(42, 81, 7)
>>> Foo()[:42]
slice(None, 42, None)

A viable alternative would be to store start and stop as separate values:

startindex = 0
stopindex = 2
print(somelist[start:stop])

Colon : operator in a list

Should I conclude that : can be used only on list not containing dict, or I am typing it wrong?

That's not a correct conclusion. : can be used with any list.

The problem is that data[0:2] is a list.
If you want to get a list of the 'key2' values of the elements in data[0:2] then you need to write that as a list comprehension:

>>> [v['key2'] for v in data[0:2]]
... ['value2', 'value4']

If you prefer to use an operator instead of a list comprehension, you can use the following:

>>> from operator import itemgetter
>>> map(itemgetter('key2'), data[0:2])
... ['value2', 'value4']

Understanding slicing

The syntax is:

a[start:stop]  # items start through stop-1
a[start:] # items start through the rest of the array
a[:stop] # items from the beginning through stop-1
a[:] # a copy of the whole array

There is also the step value, which can be used with any of the above:

a[start:stop:step] # start through not past stop, by step

The key point to remember is that the :stop value represents the first value that is not in the selected slice. So, the difference between stop and start is the number of elements selected (if step is 1, the default).

The other feature is that start or stop may be a negative number, which means it counts from the end of the array instead of the beginning. So:

a[-1]    # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items

Similarly, step may be a negative number:

a[::-1]    # all items in the array, reversed
a[1::-1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::-1] # everything except the last two items, reversed

Python is kind to the programmer if there are fewer items than you ask for. For example, if you ask for a[:-2] and a only contains one element, you get an empty list instead of an error. Sometimes you would prefer the error, so you have to be aware that this may happen.

Relationship with the slice object

A slice object can represent a slicing operation, i.e.:

a[start:stop:step]

is equivalent to:

a[slice(start, stop, step)]

Slice objects also behave slightly differently depending on the number of arguments, similarly to range(), i.e. both slice(stop) and slice(start, stop[, step]) are supported.
To skip specifying a given argument, one might use None, so that e.g. a[start:] is equivalent to a[slice(start, None)] or a[::-1] is equivalent to a[slice(None, None, -1)].

While the :-based notation is very helpful for simple slicing, the explicit use of slice() objects simplifies the programmatic generation of slicing.

Converting colon separated list into a dict?

If I understand your requirements correctly, then you can use the following one-liner.

def list_to_dict(rlist):
return dict(map(lambda s : s.split(':'), rlist))

Example:

>>> list_to_dict(['alpha:1', 'beta:2', 'gamma:3'])
{'alpha': '1', 'beta': '2', 'gamma': '3'}

You might want to strip() the keys and values after splitting in order to trim white-space.

return dict(map(lambda s : map(str.strip, s.split(':')), rlist))

How can a function accept a colon (range operator) as an argument (in Python)?

First, Python doesn't have "range operators" like some other languages. The : generates slices, which are a completely different type from ranges. And, more importantly, the : syntax is part of the slicing (aka extended indexing or extended subscription) syntax, it doesn't stand on its own.

So, the simple way to write your code is to use a slice literal:

Of course you could also avoid all this mess and just use an explicit slice literal:

def funct(x, y, n):
if n>1:
return (temp[x,y] + ints.cumtrapz(temp[x,:]*funct(slice(None),y,n-1), x=None, dx=1, initial=0)[-1])
else:
return temp[x,y]

So, why isn't there a syntax for "slice literals" that's more convenient than calling the slice constructor? Because nobody's come up with a compelling argument, worked out potential syntax ambiguities, and submitted a patch.*

* Note that Python did add a syntax for ellipsis literals on their own—... is a literal for Ellipsis, the singleton value of type ellipsis. A lot of people wanted that, there were no ambiguities except in code that was already illegal, someone wrote a patch, and it was accepted with little fuss.


While the syntax for extended indexing and the syntax for function calls are somewhat similar, they're not identical. That means you can't use function calls as, e.g., a domain-specific language for wrapping up delayed slicing.

One thing you can do is create a slice-wrapper type, to using slicing expressions themselves as such a domain-specific language:

class Slicer:
def __getitem__(self, idx):
return idx
s = Slicer()

Now s[:] is a constructor for slice(None), and s[3:23:2, ..., 4] is a constructor for (slice(3, 23, 2), Ellipsis, 4). So you can write things like this:

funct(s[:,y,n-1])

Your funct class will get a tuple of slice objects and integers, which it can later use to index an array by calling its __getitem__ directly.

And you can wrap up more of that if you want. For example:

class SliceCallable(object):
def __init__(self, f):
self.f = f
def __getitem__(self, idx):
if isinstance(idx, collections.abc.Sequence):
return self.f(*idx)
else:
return self.f(idx)
def __call__(self, *args):
return self.f(*args)

@SliceCallable
def funct(x, y, n):
if n>1:
return (temp[x,y] + ints.cumtrapz(temp[x,:]*funct[:,y,n-1], x=None, dx=1, initial=0)[-1])
else:
return temp[x,y]

Now, funct can be called as either funct(1, 2, 3) or funct[1, 2, 3]—or as funct[:, 2, 3] or funct[4:-1]. That just means that x will be slice(None, None, None) or slice(4, -1, None). And you can use that in an indexing expression; temp[slice(None, None), 3] may not look as nice as temp[:, 3], but it means the same thing.

How can a comparison operator be used with a[i:] < b[i:]?

It's comparing by Lexicographical Order

If you're trying to find the character in b (T) that is as least as big as a (T) and insert all the consecutive letters in a (A, C, O) that are smaller that character in b, this code makes sense.

~ is the biggest printable ASCII character (126), hence it's used as a comparison.

0 TACO~ AT~ False # because 'T' < 'A'
0 TACO~ T~ True # because '~' > 'A'


Related Topics



Leave a reply



Submit