assignment in a for loop

M

MackS

Hello everyone

Consider the following
.... i = i + 1
....[1, 2]

I understand (I think!) that this is due to the fact that in Python
what looks like "assignment" really is binding a name to an object. The
result is that inside the loop I am creating an object with value (i+1)
and then "pointing" the name i at it. Therefore, the object to which i
previously pointed (an element of list l) remains unchanged.

Two brief questions:

1) Is what I wrote above (minimally) correct?

2) Independently of the answer to 1, is there a way for me to assign to
elements of a list inside a loop and without resorting to C-style
ugliness of

for i in range(len(l))
l = l + 1

?

(Note: not using a list comprehension.)

Thanks in advance

Mack
 
M

MackS

Sorry, my previous post probably was not very good at explaining _why_
I want to do this.

Suppose I want to do modify all arguments which are passed to a
function. Do I need to use a list comprehension such as

def f(arg1,arg2,arg3):

arg1,arg2,arg3 = [i+1 for i in (arg1,arg2,arg3)]
...

This would be awful when, eg, one adds an argument to the function
definition. It would require edition of the code at two different
locations.

Thanks

Mack
Hello everyone

Consider the following
l = [1,2]
for i in l:
... i = i + 1
...[1, 2]

I understand (I think!) that this is due to the fact that in Python
what looks like "assignment" really is binding a name to an object. The
result is that inside the loop I am creating an object with value (i+1)
and then "pointing" the name i at it. Therefore, the object to which i
previously pointed (an element of list l) remains unchanged.

Two brief questions:

1) Is what I wrote above (minimally) correct?

2) Independently of the answer to 1, is there a way for me to assign to
elements of a list inside a loop and without resorting to C-style
ugliness of

for i in range(len(l))
l = l + 1

?

(Note: not using a list comprehension.)

Thanks in advance

Mack
 
B

Ben Finney

MackS said:
l = [1,2]
for i in l:
... i = i + 1
...[1, 2]

I understand (I think!) that this is due to the fact that in Python
what looks like "assignment" really is binding a name to an
object. The result is that inside the loop I am creating an object
with value (i+1) and then "pointing" the name i at it. Therefore,
the object to which i previously pointed (an element of list l)
remains unchanged.

That's a fair explanation, yes.
Two brief questions:

1) Is what I wrote above (minimally) correct?

Correct for what? You can tell if it's *syntactically* correct by
simply running it.

As for any other "correct", define that. Does it do what you want it
to do?
2) Independently of the answer to 1, is there a way for me to assign
to elements of a list inside a loop and without resorting to C-style
ugliness of

for i in range(len(l))
l = l + 1


You can build a new list from your operations on the old one.

new_list = []
for x in old_list:
new_list.append(x+1)

You can also do it more succinctly with a list comprehension
expression.
(Note: not using a list comprehension.)

What's preventing the use of list comprehensions?

new_list = [x+1 for x in old_list]
 
B

Ben Finney

[MackS, please don't top-post.]
Suppose I want to do modify all arguments which are passed to a
function. Do I need to use a list comprehension such as

def f(arg1,arg2,arg3):

arg1,arg2,arg3 = [i+1 for i in (arg1,arg2,arg3)]
...

This would be awful when, eg, one adds an argument to the function
definition. It would require edition of the code at two different
locations.

If you anticipate increasing the number of values passed to the
function, and you're doing the same operation on all of them, why not
pass in a list::
... """ Makes a new list with each value incremented by one. """
...
... incremented_nums = [x+1 for x in nums]
... return incremented_nums
...
>>> foo = [3, 5, 8]
>>> bar = add_one_to_each(foo)
>>> bar
[4, 6, 9]
 
M

MackS

Thank you for your reply.

Correct for what? You can tell if it's *syntactically* correct by
simply running it.

As for any other "correct", define that. Does it do what you want it
to do?

I was referring to my attempted explanation, not the code snippet.
[...]

What's preventing the use of list comprehensions?

new_list = [x+1 for x in old_list]

Suppose I want to do anything as trivial as modify the values of the
list members _and_ print their new values. List comprehensions must not
contain statements, I think.


Mack
 
D

Dennis Lee Bieber

def f(arg1,arg2,arg3):

arg1,arg2,arg3 = [i+1 for i in (arg1,arg2,arg3)]
...

This would be awful when, eg, one adds an argument to the function
definition. It would require edition of the code at two different
locations.
Uh... As written, the left hand side will require changes anyway...
Also, you have to remember that (again, as written) in Python arguments
are input only unless you pass a mutable object.
.... return tuple([i+1 for i in arg])
.... --
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
B

Ben Finney

MackS said:
Thank you for your reply.

A pleasure to help.
What's preventing the use of list comprehensions?

new_list = [x+1 for x in old_list]

Suppose I want to do anything as trivial as modify the values of the
list members _and_ print their new values. List comprehensions must
not contain statements, I think.

You're correct, but that's because you're creating a new list, not
modifying the existing one. The list comprehension can do anything you
like to generate each element, so long as it's an expression::
>>> foo = [3, 5, 8]
>>> print [x+1 for x in foo] [4, 6, 9]
>>> print [x**2 for x in foo] [9, 25, 64]
>>> print [str(x**2) for x in foo] ['9', '25', '64']
>>> print [len(str(x**2)) for x in foo]
[1, 2, 2]

If it's too complex to be readable in a single expression, make it a
function which returns a value, since calling a function is itself an
expression::
... quad = n**4
... if len(str(quad)) % 2:
... word = "spam"
... else:
... word = "eggs"
... result = word.strip("s").title()
... return result
...
>>> foo = [3, 5, 8]
>>> print [get_result_of_complex_stuff(x) for x in foo]
['Egg', 'Pam', 'Egg']

Once you have your new list being created by a list comprehension, do
what you like with it. If you want it to be stored, assigned back to
the original name, each value printed, or whatever you like, then do
so::
>>> bar = [get_result_of_complex_stuff(x) for x in foo]
>>> foo = bar
>>> for x in foo:
... print x,
...
Egg Pam Egg
 
B

bruno at modulix

MackS wrote:
(snip)
What's preventing the use of list comprehensions?

new_list = [x+1 for x in old_list]

Suppose I want to do anything as trivial as modify the values of the
list members _and_ print their new values.

Then it's a sure design smell IMHO. Don't mix presentation with logic.
List comprehensions must not
contain statements, I think.

You're right.
 

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,770
Messages
2,569,586
Members
45,089
Latest member
Ketologenic

Latest Threads

Top