Reputation: 1041
I want to initialize a list in python. I do not understand why the code below does not work:
u = ['abc', 'de', 'fghi', 'jklm', 'n', '']
for item in u:
item = len(item)
There are other ways to initialize the list, like:
u = [len(item) for item in u]
But, my question is why the first code does not work.
Edit:
I am a newbie to Python, and programming. Unfortunately I do not understand some parts of your answers. For example:
- rebinding in "rebinding the name item
to the length of the name item
"
- iterator in "item" is a temporary variable that points to an element of a u
based on where the (implicit) iterator is pointing
As far as I understand, my second example, creates a new_list
in memory, and assigns the values of new_list
to u
. No matter what the previous values were. But I want to know how I can change the values, in the first list. Thanks
Upvotes: 7
Views: 562
Reputation: 189
item
is just a name. in the for
loop:
for item in u:
the item
is a reference to the object to which u[i] refers. In other words, item
and u[i]
refer to the same object.
but this statement:
item = len(item)
change the name item
to refer to a int, whose value is len(item).
So nothing changed in the list u.
The list comprehension:
u = [len(item) for item in u]
is just create a new list, and the name u is now a reference to the new list.
If you want to use for loop, you can use the enumerate
statement:
for i, item in enumerate(u):
u[i] = len(item)
That changes the referrings of the items of u one by one.
Upvotes: 0
Reputation: 13869
The reason the first code doesn't work is because item
is just a reference to each iterable object in the sequence u
. When you say item = len(item)
you actually do assign len(item)
to item
, but since item
was just acting as a reference pointer pointing to u[i]
for the i*th* step in your loop, it won't actually change u[i]
itself.
To change u[i]
you can do list comprehension like you showed in your question, or do something like:
for i in range(len(u)):
u[i] = len(u[i])
A third way is the very useful enumerate
method introduced in python 2.3.
for i, item in enumerate(u):
u[i] = len(item)
Enumerate
returns a list of tuples created from its argument (don't quote me on this...but it basically acts as a list of tuples) where each tuple inside is of the form (index, argument[index]).
Upvotes: 1
Reputation: 208475
You cannot change the contents of a list just by assigning a new value to a name that represents an entry in that list. You need to use index assignment, for example to change the first entry in the list to 'foo'
you could do u[0] = 'foo'
.
In this case you could do something like the following (although the list comprehension from you question is cleaner):
for i, item in enumerate(u):
u[i] = len(item)
Note that if the items in your list are mutable you can modify the element directly, you just can't reassign them. For example with a list of lists:
u = [['a'], ['b', 'c']]
for item in u:
item.append(len(item))
# u is now [['a', 1], ['b', 'c', 2]]
Upvotes: 1
Reputation: 10575
The first code does work. The list u
is initialized in the first line and the next two lines execute having no effect on the rest of the code - there's no point to them.
u = ['abc', 'de', 'fghi', 'jklm', 'n', '']
Is initializing the list u
with contents ['abc', 'de', 'fghi', 'jklm', 'n', '']
- that's all you need to do to initialize a list.
The lines
for item in u:
item = len(item)
Just bind the name item
to all the values in u
immediately after rebind item
to the length property of the value one-by-one until the interpreter has worked through the whole list.
Upvotes: 0
Reputation: 4666
In the first case, you are not initializing anything. "item" is a temporary variable that points to an element of a u based on where the (implicit) iterator is pointing. If you want to initialize a list in the first style, you can do so as:
u = ['abc', 'de', 'fghi', 'jklm', 'n', '']
v = []
for item in u:
v.append(len(item))
print v
Upvotes: 4
Reputation: 25662
You're rebinding the name item
to the length of the name item
that was just bound by the loop. You cannot initialize a list
in this way. All you're doing is rebinding a variable in each iteration. Your list comprehension is a perfectly acceptable method for initializing a list
.
Upvotes: 3