Erich Purpur
Erich Purpur

Reputation: 1529

Python - Change item value in list

I have some data I have zipped together using itertools.zip_longest

import itertools
names = 'Tim Bob Julian Carmen Sofia Mike Kim Andre'.split()
locations = 'DE ES AUS NL BR US'.split()
confirmed = [False, True, True, False, True]
zipped_up = list(itertools.zip_longest(names, locations, confirmed))

if I print zipped_up the way it is now I get the following:

[('Tim', 'DE', False), ('Bob', 'ES', True), 
('Julian','AUS', True), ('Carmen', 'NL', False), 
('Sofia', 'BR',True), ('Mike', 'US', None), 
('Kim',None, None),('Andre', None, None)]

This is fine, the missing values are given "None" as a default. Now I want to change the "None" values to '-'.

It seems like I should be able to do so in the following nested loops. If I include a print statement in the code below, it appears everything works the way I wanted:

for items in zipped_up:
    for thing in items:
        if thing == None:
            thing = '-'
        print(thing)

But if I print zipped_up again (outside the loops), the 'None' values have not changed. Why Not? Is it something to do with the data type of the list items, which are tuples?

I have referenced some other stackoverflow threads including this one but have been unable to use it: finding and replacing elements in a list (python)

Upvotes: 1

Views: 1687

Answers (2)

MarianD
MarianD

Reputation: 14201

First, you are trying to change elements in tuples, but tuples are immutable objects.
The only way to "change" them is to create new ones on the basis of existing ones.

Second, this part of your code

for thing in items:
    if thing == None:
        thing = '-'

replaces only the content of the variable thing, so even if you would have mutable objects in your zipped_up list - such as (nested) lists - your code would not change them anyway.

So, if your for whatever reason don't want to accept the solution of sacul and instead edit your loop in loop approach, you may append newly created tuples to the new, empty list.

As in this (not very nice) code:

result = []
for a, b, c in zipped_up:
    a = '-' if a is None else a
    b = '-' if b is None else b
    c = '-' if c is None else c
    result.append((a, b, c))

print(result)

Output:

[('Tim', 'DE', False), ('Bob', 'ES', True), ('Julian', 'AUS', True), ('Carmen', 'NL', False), ('Sofia', 'BR', True), ('Mike', 'US', '-'), ('Kim', '-', '-'), ('Andre', '-', '-')]

Upvotes: 3

sacuL
sacuL

Reputation: 51425

Simply use the fillvalue argument:

zipped_up = list(itertools.zip_longest(names, locations, confirmed, fillvalue='-'))

>>> zipped_up
[('Tim', 'DE', False), ('Bob', 'ES', True), ('Julian', 'AUS', True), ('Carmen', 'NL', False), ('Sofia', 'BR', True), ('Mike', 'US', '-'), ('Kim', '-', '-'), ('Andre', '-', '-')]

Upvotes: 5

Related Questions