18

I have a list of lists, each list within the list contains 5 items, how do I change the values of the items in the list? I have tried the following:

    for [itemnumber, ctype, x, y, delay] in execlist:
        if itemnumber == mynumber:
            ctype = myctype
            x = myx
            y = myy
            delay = mydelay

Originally I had a list of tuples but I realized I cant change values in a tuple so I switched to lists but I still cant change any of the values. If I print ctype, x, y, delay, myctype, myx, myy, or mydelay from within the for loop it appears that everything is working but if I print execlist afterwards I see that nothing has changed.

1
  • Are itemnumbers unique? Or is there another reason why you want to iterate through the entire list, even after a replacement has been done? Commented Dec 6, 2012 at 21:06

8 Answers 8

17

The problem is that you are creating a copy of the list and then modifying the copy. What you want to do is modify the original list. Try this instead:

for i in range(len(execlist)):
    if execlist[i][0] == mynumber:
         execlist[i][1] = myctype
         execlist[i][2] = myx
         execlist[i][3] = myy
         execlist[i][4] = mydelay
0
4

You could use enumerate():

for index, sublist in enumerate(execlist):
   if sublist[0] == mynumber:
       execlist[index][1] = myctype
       execlist[index][2] = myx
       execlist[index][3] = myy
       execlist[index][4] = mydelay
       # break

You can remove the # if execlist only contains at most one sublist whose first item can equal mynumber; otherwise, you'll cycle uselessly through the entire rest of the list.

And if the itemnumbers are in fact unique, you might be better off with a dictionary or at least an OrderedDict, depending on what else you intend to do with your data.

3

You need to assign via indexes. Let's say you've got a list of lists, where the inner lists each have 5 items like you describe. If you want to iterate through them and change the value of the second item in each inner list, you could do something like:

l = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]
for i in l:
    i[1] = "spam"

print l
(output) [[0, "spam", 2, 3, 4], [5, "spam", 7, 8, 9], [10, "spam", 12, 13, 14]]
1

Variable unpacking does not seem to pass the reference but copies the values. An solution would be to do it like this:

foo = [[1, "gggg"], [3, "zzzz"]]

for item in foo:
    item[0] = 2
    item[1] = "ffff"

print(foo)

>>>> [[2, 'ffff'], [2, 'ffff']] 
0

Don't assign local variables in lists. In the loop

for i in lis:
    i = 5

Just sets the variable i to 5 and leaves the actual contents of the list unchanged. Instead, you have to assign it directly:

for i in range(len(lis)):
     lis[i] = 5

The same applied for lists of lists, although in this case the local variable doesn't have to be assigned so you can use the for...in construct.

for i in listoflists:
     for i2 in range(len(i)):
          i[i2] = 5 #sets all items in all lists to 5
0

Changing the variables assigned in the for does not change the list. Here's a fairly readable way to do what you want:

execlist = [
    #itemnumber, ctype, x, y, delay
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10],
    [11, 12, 13, 14, 15],
]

mynumber, myctype, myx, myy, mydelay = 6, 100, 101, 102, 104

for i, sublist in enumerate(execlist):
   if sublist[0] == mynumber:
        execlist[i] = [mynumber, myctype, myx, myy, mydelay]

print execlist

Output:

[[1, 2, 3, 4, 5], [6, 100, 101, 102, 104], [11, 12, 13, 14, 15]]
0

The iterator variables are copies of the original (Python does not have a concept of a reference as such, although structures such as lists are referred to by reference). You need to do something like:

for item in execlist:
    if item[0] == mynumber:
        item[1] = ctype
        item[2] = myx
        item[3] = myy
        item[4] = mydelay

item itself is a copy too, but it is a copy of a reference to the original nested list, so when you refer to its elements the original list is updated.

This isn't as convenient since you don't have the names; perhaps a dictionary or class would be a more convenient structure.

0

Here is an example I used recently, it was a real mind bender but hopefully it can help out some one!

pivot_peaks is a list of pandas data frames some of them are duplicates.

# Create a new list with only a single entry for each item
new_list = []

for obj_index, obj in enumerate(pivot_peaks):
    add_new_frame = False

    if len(new_list) == 0:
        new_list.append(obj)
    else:
        for item in new_list:
            if item.equals(obj):
                add_new_frame = False
                break
            else:
                add_new_frame = True

        if add_new_frame == True:
            new_list.append(obj)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.