Addressing the last element of a list

P

pinkfloydhomer

Or alternatively:

Is there a way to make reference to the last element of a list, to use
as a shorthand:

ref := &lst[len(lst) - 1] # I know syntax is wrong, but you get the
idea

and then using the last element of the list by (assuming the element is
a dict):

ref["foo"] = 42
ref["bar"] = "Ni!"

etc.

/David
 
P

pinkfloydhomer

I knew there was an easy way :)

Just to satisfy my curiousity: Is there a way to do something like the
reference solution I suggest above?
 
J

Jerzy Karczmarczuk

Peter said:
No. You cannot overload assignment.

I have the impression that this is not an issue, to overload assignments,
which btw. *can* be overloaded, but the absence of *aliasing* (undiscriminate
handling of pointers) in Python. Am I wrong?

Jerzy Karczmarczuk
 
P

pinkfloydhomer

I just want an alias. Ideally, I don't want to deal with pointers or
special reference "types" etc. After all, this is not C++ :)

I just want to be able to make a reference to any old thing in Python.
A list, an integer variable, a function etc. so that I, in complicated
cases, can make a shorthand. If "myRef" could somehow "point at"
something long an complicated like a[42]["pos"][-4], that might be
useful.

/David
 
P

pinkfloydhomer

But if lst[42]["pos"] happens to hold an integer value, then

a = lst[42]["pos"]

will _copy_ that integer value into 'a', right? Changing 'a' will not
change the value at lst[42]["pos"]
 
B

Bengt Richter

I knew there was an easy way :)

Just to satisfy my curiousity: Is there a way to do something like the
reference solution I suggest above?

If the last element in the list was a dict, then you could do something like
>>> lst = ['the', 'last', 'element of this list is a dict', {'key':"key's value"}]
>>> ref = lst[-1]
>>> ref {'key': "key's value"}
>>> ref["foo"] =42
>>> ref['bar'] = 'Ni!'
>>> ref {'foo': 42, 'bar': 'Ni!', 'key': "key's value"}
>>> ref['key'] "key's value"
>>> ref['bar'] 'Ni!'
>>> del ref['key']
>>> ref
{'foo': 42, 'bar': 'Ni!'}

FWIW ;-)

Regards,
Bengt Richter
 
S

Simon Brunning

But if lst[42]["pos"] happens to hold an integer value, then

a = lst[42]["pos"]

will _copy_ that integer value into 'a', right?

Nope. It will bind the name 'a' to the integer object.
Changing 'a' will not
change the value at lst[42]["pos"]

Integers are immutable - they can't be modified. So, "Changing 'a'"
means binding the name 'a' to a different object. This will have no
effect on other references to the original object.

Reset your brain - <http://effbot.org/zone/python-objects.htm>.
 
P

Peter Otten

Jerzy said:
I have the impression that this is not an issue, to overload assignments,
which btw. *can* be overloaded, but the absence of *aliasing*
(undiscriminate handling of pointers) in Python. Am I wrong?

I think so.

a = b

will always make a a reference to (the same object as) b. What can be
overloaded is attribute assignment:

x.a = b

can do anything from creating an attribute that references b to wiping your
hard disk.

I don't understand what you mean by "absence of aliasing", but conceptually
every python variable is a -- well-behaved -- pointer.

Peter
 
B

Bengt Richter

But if lst[42]["pos"] happens to hold an integer value, then

a = lst[42]["pos"]

will _copy_ that integer value into 'a', right? Changing 'a' will not
change the value at lst[42]["pos"]

Right, but try an example:
>>> lst = range(42)+[{'pos':123}]+range(43,50)
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 2
6, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, {'pos': 123}, 43, 44, 45, 46, 47,
48, 49]
>>> lst[41:44] [41, {'pos': 123}, 43]
>>> lst[42] {'pos': 123}
>>> lst[42]['pos'] 123
>>> a = lst[42]['pos']
>>> a 123
>>> lst[42]['pos'] 123
>>> id(lst[42]['pos']) 49421860
>>> id(a)
49421860

IOW, a is now an alias for the same 123 immutable integer object as is referred to by the 'pos' key
in the dict which is the 43rd element (index 42) of lst.

Regards,
Bengt Richter
 
B

bonono

If you want to do what you want(though I don't know why without a
concrete example), just store a mutable object at lst[42]["pos"], like
this :

lst[42]["pos"] = [1]

a = lst[42]["pos"]
a[0] = 2
assert(lst[42]["pos"][0] == 2)
 
P

Peter Otten

I just want an alias. Ideally, I don't want to deal with pointers or
special reference "types" etc. After all, this is not C++ :)

I just want to be able to make a reference to any old thing in Python.
A list, an integer variable, a function etc. so that I, in complicated
cases, can make a shorthand. If "myRef" could somehow "point at"
something long an complicated like a[42]["pos"][-4], that might be
useful.

You can do

shorthand = a[42]["pos"]

....

print shorthand[-4]
shorthand[0] = 42 # if a[42]["pos"] is mutable

But the last indirection must always be given explicitly.

Peter
 
J

Jerzy Karczmarczuk

Peter Otten wrote cites me:
I think so.

a = b

will always make a a reference to (the same object as) b. What can be
overloaded is attribute assignment:

x.a = b

can do anything from creating an attribute that references b to wiping your
hard disk.

I don't understand what you mean by "absence of aliasing", but conceptually
every python variable is a -- well-behaved -- pointer.

Would you please concentrate on - what I underlined - the sense of "C" aliasing,
where you can make a pointer to point to anything, say, the 176th byte of a
function code?

*This* is impossible in Python. What you wrote is OK, but I still don't know
where I have been wrong, unless you over-interpret my words. Sure, I didn't
want to claim that the assignment a=anything can be plainly overloaded. But
getitem, setitem, getattr, setattr - yes. And they (set-) are also assignments.

Jerzy Karczmarczuk
 
P

Peter Otten

Just to satisfy my curiousity: Is there a way to do something like the
reference solution I suggest above?

No. You cannot overload assignment.
Of course, for mutable objects you can use the object as the "reference" to
itself.

Peter
 
P

Peter Otten

Jerzy said:
Sure, I didn't want to claim that the assignment a=anything can be plainly
overloaded.

I interpreted your previous post as such a claim. No disagreement here then.
Would you please concentrate on - what I underlined - the sense of "C"
aliasing, where you can make a pointer to point to anything, say, the
176th byte of a function code?

I've never heard the expression "aliasing" for that, sorry.
This is impossible in Python.

Of course, but I don't think this is what the OP wanted.

Peter
 
M

Matt Hammond

Would you please concentrate on - what I underlined - the sense of "C"
aliasing,
where you can make a pointer to point to anything, say, the 176th byte
of a
function code?

Pretty much everything is referred to by reference in python. The big
difference is that most
primitive data types (integer, string) etc... aren't mutable - you can't
change them in place - instead you replace them with a new instance
containing the new/modified value.

But your own object and lists are mutable - you can change their
attributes. So encapsulate data within a list or as an attribute of an
object and you've got the effect you're after.

For example:
(6, 5)

Whereas:
([6], [6])

Note that reassigning a:
causes a to point to a new list, containing the value 6, whereas the 2nd
example above modified the list by replacing an element of it.


Hope this helps


Matt

--

| Matt Hammond
| R&D Engineer, BBC Research & Development, Tadworth, Surrey, UK.
| http://kamaelia.sf.net/
| http://www.bbc.co.uk/rd/
 
G

Giovanni Bajo

I just want an alias.

What you want is impossible. But there are many workarounds.
I just want to be able to make a reference to any old thing in Python.
A list, an integer variable, a function etc. so that I, in complicated
cases, can make a shorthand. If "myRef" could somehow "point at"
something long an complicated like a[42]["pos"][-4], that might be
useful.


One simple workaround:

def createAlias(L, idx1, idx2, idx3):
def setval(n):
L[idx1][idx2][idx3] = n
return setval

k = createAlias(a, 42, "pos", -4)

[...]

n = computeValue(...)
k(n) # store it!


You will also find out that your case is actually very unlikely in
well-designed code. You don't usually work with stuff with three level of
nesting like a[][][], since it gets totally confusing and unmaintanable. You
will end up always with objects with better semantic, and methods to modify
them. So in the end you will always have a reference to the moral equivalent of
a[42]["pos"], and that would be a well defined object with a method setThis()
which will modify the moral equivalent of [-4].
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top