18

I'm looking for a clean way to iterate over a list of tuples where each is a pair like so [(a, b), (c,d) ...]. On top of that I would like to alter the tuples in the list.

Standard practice is to avoid changing a list while also iterating through it, so what should I do? Here's what I kind of want:

for i in range(len(tuple_list)):
  a, b = tuple_list[i]
  # update b's data
  # update tuple_list[i] to be (a, newB)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Clev3r
  • 1,568
  • 1
  • 15
  • 28
  • Well, you're not really updating the list with that one, you're only updating the tuple. – Some programmer dude Feb 14 '13 at 17:07
  • Right, so something like `tuple_list[i] = (a, newB)`... except I want to avoid doing this inside the loop. I'm curious if there's a cleaner way. – Clev3r Feb 14 '13 at 17:08
  • 1
    @Clever: The loop you've given is fine; it doesn't iterate through the list you're updating but just the indexes. This is a completely standard way to work with lists, as long as you're not changing the number of elements in the list, which you're not. – John Y Feb 14 '13 at 17:11

3 Answers3

36

Just replace the tuples in the list; you can alter a list while looping over it, as long as you avoid adding or removing elements:

for i, (a, b) in enumerate(tuple_list):
    new_b = some_process(b)
    tuple_list[i] = (a, new_b)

or, if you can summarize the changes to b into a function as I did above, use a list comprehension:

tuple_list = [(a, some_process(b)) for (a, b) in tuple_list]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
4

Why don't you go for a list comprehension instead of altering it?

new_list = [(a,new_b) for a,b in tuple_list]
Udo Klein
  • 6,784
  • 1
  • 36
  • 61
0

here are some ideas:

def f1(element):
    return element

def f2(a_tuple):
    return tuple(a_tuple[0],a_tuple[1])

newlist= []
for i in existing_list_of_tuples :
    newlist.append( tuple( f1(i[0]) , f(i1[1]))

newlist = [ f2(i) for i in existing_list_of_tuples ]
Jonathan Vanasco
  • 15,111
  • 10
  • 48
  • 72