1

With given list:

x = [x for x in range(10)]

Printing out indexes and values:

for i in range(-10, len(x)):
    print i, ": ", x[i]

The output is:

-10 :  0
-9 :  1
-8 :  2
-7 :  3
-6 :  4
-5 :  5
-4 :  6
-3 :  7
-2 :  8
-1 :  9
0 :  0
1 :  1
2 :  2
3 :  3
4 :  4
5 :  5
6 :  6
7 :  7
8 :  8
9 :  9

but

print x

returns:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Why is the actual list twice as long as the initialized list?

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
Steven Senko
  • 127
  • 5

3 Answers3

12

You are using negative indexes. Those work too; in Python an index < 0 indexes from the end. So there are two different ways of indexing elements, counting from the start and from the end.

For example, the index 2 and -8 both refer to the 3rd element in x, so both indexes give you the value 2.

As such, the list is not twice as long, you are just printing the values twice; once for the negative index, and once again for the positive.

See note #3 under the sequence types operations table:

  1. If i or j is negative, the index is relative to the end of the string: len(s) + i or len(s) + j is substituted. But note that -0 is still 0.

or from the Introduction section of the Python tutorial:

Indices may also be negative numbers, to start counting from the right:

>>> word[-1]  # last character
'n'
>>> word[-2]  # second-last character
'o'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
6

Python support negative indexes as well as positive indexes to access an element of a list.

In negative indexes, an element is accessed from the end of the list counting backwards.

So,
Element at index -1 is basically the last element of the list i.e. element at index 9.
Element at index -2 is the second last element i.e element at index 8.
..
..
Element at index -10 is the first element i.e element at index 0.

Your list size is not double. You are just printing out the same element twice when infact they are the same object, you are just using 2 different ways to access the same object.

You can check that they are the same using the is operator.

>>> x[0] is x[-10] # Both point to the same object
True

>>> x[1] is x[-9] # Both point to the same object
True
...
...
>>> x[9] is x[-1] # Both point to the same object
True
Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126
  • 1
    Better to use `==` than `is` for Python strings – rassa45 Jul 11 '15 at 16:25
  • `==` checks for equality but `is` will infact check for the object identity. – Rahul Gupta Jul 11 '15 at 16:29
  • So `a is b` will be `True` only if `a` and `b` are the same object. – Rahul Gupta Jul 11 '15 at 16:30
  • @ytpillai, can you elaborate? Two equal `str`s (or `int`s for that matter) created separately by literals are identical: e.g. this snippet `x = 'a'; y = 'a'; x is y` returns `True`. – werkritter Jul 11 '15 at 16:32
  • 2
    Yes, but if you have two different objects of the same value, this will not work. If `a = [1, 2, 3]` and `b = a`, then `b is a[:]` is false but `b == a[:]` is true. http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python – rassa45 Jul 11 '15 at 16:38
  • OK, but my point (and your initial remark) concerns `int`s and `str`s specifically. From my example it looks like that `str`s with the same values are always identical. You can even try: `x = 'abc'; y = x[:]; x is y` (it returns `True`). So again: why is it better to use `==` than `is` for `str`s? – werkritter Jul 11 '15 at 16:46
  • 1
    Ah, I read up the question pointed by you and it indeed seems that it is better to use `==` — for both `int`s and `str`s: "In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work". So I stand corrected. :) And thanks for the interesting link! – werkritter Jul 11 '15 at 16:52
  • 2
    `lst = [1, 1, 1]; lst[0] is lst[1] -> True; lst[1] is lst[2] -> True`. Both indices mean the same thing to Python **vs** two indices point to the same object are two different things. – Ashwini Chaudhary Jul 11 '15 at 17:11
0

An array of 10 elements in python,

x of index     0   1  2  3  4  5  6  7  8  9
= x of index  -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 

see python 2.7 documentation tutorial

In your code:

for i in range(-10, len(x)):
    print i, ": ", x[i]

would have i run from -10 to len(x)-1, which in detail = -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, ..., 9.

That's 20 iterations in total, which explains why you get twice as len(x).

I guess what you want is:

for i in range(-len(x), 0):
    print i, ": ", x[i]

This would give normal size = len(x).