2

I'm struggling to print the 2d list by replacing the strings 7 and 9 by A and B. What am i doing wrong? Is there a better way of doing this?

The function is supposed to go through the 2d list and when it finds the items 7 or 9, it replaces them by A and B and prints the changed 2d list.

I get this error: TypeError: list indices must be integers or slices, not list

This is my code:

A = 7
B = 9

def display_list(A, B):
mylist = [("01","02","03","04","05","06","07"),("08","09","10","11","12","13","14"),("15","16","17","18","19","20","21")]

    for row in mylist:
        row = list(map(int, row))
        for i in range(len(row)):
            if row[i] == A:
                row[i] = "A"
            row = list(map(str, row))
            if row[i] == B:
                row[i] = "B"
        row = list(map(str, row))

    mylist[row] = row
    print(mylist)

display_list(A,B)

What I want is:

[("01","02","03","04","05","06","A"),("08","B","10","11","12","13","14"),("15","16","17","18","19","20","21")]
7
  • 1
    What is the expected output you are looking for? Commented Jun 18, 2017 at 13:17
  • What are you trying to achieve? Commented Jun 18, 2017 at 13:17
  • What I want is to replace the strings 7 and 9 in the 2d list by A and B. Commented Jun 18, 2017 at 13:22
  • @user1236969 I suggest you edit your question, clearly stating what is the problem you are trying to solve. What is the goal of the problem exactly so the readers can understand what it is that this function is really supposed to do in general. Commented Jun 18, 2017 at 13:23
  • OK. tuples are immutable. Did you create this data structure of a list of tuples yourself? If you have control over the data structure, you can significantly simplify this problem by making a structure that has the expectation that data could change. Commented Jun 18, 2017 at 13:27

2 Answers 2

5

You can create a simple lookup map and just loop through your data to find the replacements, something like:

def display_list(A, B):
    data = [("01", "02", "03", "04", "05", "06", "07"),
            ("08", "09", "10", "11", "12", "13", "14"),
            ("15", "16", "17", "18", "19", "20", "21")]
    lookup_map = {A: "A", B: "B"}  # a simple lookup map for our search
    return [tuple(lookup_map.get(int(e), e) for e in s) for s in data]

A = 7
B = 9 

test_list = display_list(A, B)
# [('01', '02', '03', '04', '05', '06', 'A'),
#  ('08', 'B', '10', '11', '12', '13', '14'),
#  ('15', '16', '17', '18', '19', '20', '21')]

Or, if you really want to do it long way around with manual checks:

def display_list(A, B):
    data = [("01", "02", "03", "04", "05", "06", "07"),
            ("08", "09", "10", "11", "12", "13", "14"),
            ("15", "16", "17", "18", "19", "20", "21")]  # our source list
    result = []  # create an empty result list
    for sublist in data:  # loop through our source list of tuples
        tmp_result = []  # create a temporary storage list
        for element in sublist:  # loop through each of the tuples from the source list
            value = int(element)  # convert the element to integer for comparison
            if value == A:  # if the element's value is the same value as A
                tmp_result.append("A")  # add "A" to our temporary storage list
            elif value == B: # else, if the element's value is the same value as B
                tmp_result.append("B")  # add "B" to our temporary storage list
            else:  # if no match
                tmp_result.append(element)  # just add the original element
        result.append(tuple(tmp_result))  # convert the temp list to tuple, add to the result
    return result  # return the result

And finally, if you want to do an in-place replacement (instead of temporary lists) like you attempted in your question:

def display_list(A, B):
    data = [("01", "02", "03", "04", "05", "06", "07"),
            ("08", "09", "10", "11", "12", "13", "14"),
            ("15", "16", "17", "18", "19", "20", "21")]  # source list
    for i, sublist in enumerate(data):  # loop through our source list, including an index
        sublist = list(sublist)  # convert the tuples into lists for modification
        for j, element in enumerate(sublist):  # loop through the sublist, including an index
            value = int(element)  # convert the element to integer for comparison
            if value == A:  # if the element's value is the same value as A
                sublist[j] = "A"  # replace the current element with "A"
            elif value == B:  # else, if the element's value is the same value as B
                sublist[j] = "B"  # replace the current element with "B"
        data[i] = tuple(sublist)  # convert back to a tuple and update the current list
    return data  # return the modified source data
Sign up to request clarification or add additional context in comments.

7 Comments

Yes, however, based on the code in question, I think it is the other way around. A and B are holding values 7 and 9.
@idjaw - as far as I understood the OP, he wants to replace values of A and B with literal A and B when/if they occur in the list of tuples.
Oh, so I got it completely wrong... Is there no other way to do this?
@zwer yeah...you're right. This is all too early for me. goes back to drinking coffee.
@user1236969 - there is, check the above update... but that's a significantly less performant way to do it and some would call it un-Pythonic...
|
0

Using list comprehension:

def display_list(A, B):
    mylist = [("01","02","03","04","05","06","07"),
              ("08","09","10","11","12","13","14"),
              ("15","16","17","18","19","20","21")]

    mylist = [tuple("A" if int(element) == A 
                        else "B" if int(element) == B else element 
                        for element in list(row)) 
                        for row in mylist ]
    print(mylist)

To understand it may easier to do long way of above, i.e. change each row of tuple to list and replace the elements of the list when matches and convert back to tuples since tuples are immutable.

def display_list(A, B):

    mylist = [("01","02","03","04","05","06","07"),
              ("08","09","10","11","12","13","14"),
              ("15","16","17","18","19","20","21")]

    for row_index in range(len(mylist)):

        # tuples are immutable so converting it to list
        elements_list = list(mylist[row_index])

        # finding an replacing the elements in the list 
        # when matches using list comprehension
        elements_list = ["A" if int(element) == A 
                             else "B" if int(element) == B 
                                      else element # no match leave as it is
                             for element in elements_list]

        # converting list back to tuples and assigning to mylist the updated tuples
        mylist[row_index] = tuple(elements_list)

    print(mylist)

A = 7
B = 9
display_list(A,B)

Comments

Your Answer

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