1

I am trying to take a 2D list and print out the individuals list inside.

Something like: If the user enters the 2D list: "[[a,b],[c,d],[e],[f,g]]"

Required output should be:

[a,b]
[c,d]
[e]
[f,g] 
The following is the current code I have but it does not work as intended:
alist = []
UserInput = input("Enter 2D list = ")
alist.append(UserInput)
        
for row in alist:
    print(row)
Prakash Dahal
  • 4,388
  • 2
  • 11
  • 25
  • `input` returns a *string*. The following string: `"[[a,b],[c,d],[e],[f,g]]"` would represent a valid list literal (which is *source code*, i.e. text), but if you evaluated that text as source code it would raise a `NameError`, because non of the variables you referenced are defined – juanpa.arrivillaga Nov 12 '21 at 00:33

2 Answers2

0

(I'm new on stack overflow so I don't know if I'm answering correctly). You have to replace just 3 line of your code:

list = list(eval(input(" Enter 2D list = "))
for row in list: 
    print(row)
  • 1
    Welcome to StackOverflow! Some python tips: 1) ast.literal_eval() is generally preferable to eval(). If you're working with untrusted input, then you should use ast.literal_eval(), because it won't evaluate arbitrary code. See https://stackoverflow.com/questions/21661090/python3-best-alternatives-to-eval-input-as-an-expression 2) You should avoid using variables named "list", because they will shadow the built-in function list. – Nick ODell Nov 12 '21 at 00:58
0

There is a key difference between these two strings:

str1 = "[['a','b'],['c','d'],['e'],['f','g']]"

str2 = "[[a,b],[c,d],[e],[f,g]]"

The first string (str1) is a pure representation of string list of lists which have strings inside lists. But in the second string (str2), the list of lists is made up of variables like a, b, c. These are not strings and will cause error if you try to print the lists of it. Check this:

print([[a,b],[c,d],[e],[f,g]])  # will throw error as undefined variables

The first string (str1) can be easily convert to list of lists using ast

Check this:

import ast
str1 = "[['a','b'],['c','d'],['e'],['f','g']]"

str_lists = ast.literal_eval(str1)

for lst in str_lists :
    print(lst)

#Output
>>> ['a', 'b']
    ['c', 'd']
    ['e']
    ['f', 'g']

In your case

Your case is likely to be the case of second string (str2) since it will assume the list as a whole string itself.

str2 = "[[a,b],[c,d],[e],[f,g]]"

If you try to use ast in this case, it will throw error as it contains variables inside list instead of strings.

str2 = "[[a,b],[c,d],[e],[f,g]]"

str_lists = ast.literal_eval(str2)

# it throws error
for lst in str_lists:
    print(lst)

So, in order to solve this, you need to use the concept of stack for balanced parentheses. Check this

Solution:

def convert_to_list(myStr):
    open_list = ["[","{","("]
    close_list = ["]","}",")"]
    
    myStr = myStr.replace(',',' ')
    stack = []
    stack_ind = []
    new_list = []
    for innd, i in enumerate(myStr):
        if i in open_list:
            stack.append(i)
            stack_ind.append(innd)
        elif i in close_list:
            pos = close_list.index(i)
            
            if ((len(stack) > 0) and
                (open_list[pos] == stack[len(stack)-1])):
                nstr = myStr[stack_ind[-1]+1:innd]
                new_list.append(nstr.split())
                stack.pop()
    new_list.remove(new_list[-1])
    return new_list

UserInput = input("Enter 2D list = ")
input_list = convert_to_list(UserInput)
for lst in input_list:
    print(lst)

#Output
>>>  ['a', 'b']
     ['c', 'd']
     ['e']
     ['f', 'g']
Prakash Dahal
  • 4,388
  • 2
  • 11
  • 25