Open In App

Python – Convert delimiter separated Mixed String to valid List

Last Updated : 02 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string with elements and delimiters, split elements on delimiter to extract with elements ( including containers).

Input : test_str = “6*2*9*[3, 5, 6]*(7, 8)*8*4*10”, delim = “*” 
Output : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10] 
Explanation : Containers and elements separated using *.

Input : test_str = “[3, 5, 6]*(7, 8)*8*4*10”, delim = “*” 
Output : [[3, 5, 6], (7, 8), 8, 4, 10] 
Explanation : Containers and elements separated using *. 

Method #1 :  Using loop + eval() + split()

This is one way in which this task can be done. In this the separation is done using split() and eval() does the important task of performing the evaluation of data types to be containers or simpler elements. 

Step-by-step approach:

  • Initialize the input string test_str.
  • Print the original input string.
  • Initialize the delimiter string delim.
  • Split the input string using the split() function and the delimiter string delim.
  • Initialize an empty list res to store the final output.
  • Use a loop to iterate over the split string elements in temp.
    • Use the eval() function to evaluate the string representation of the element and convert it into the required type.
    • Append the converted element to the res list.
  • Print the final list res after conversion.

Below is the implementation of the above approach:

Python3




# Python3 code to demonstrate working of
# Convert delimiter separated Mixed String to valid List
# Using loop + split() + eval()
 
# initializing string
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
 
# printing original string
print("The original string is : " + str(test_str))
 
# initializing delim
delim = "#"
 
# splitting using split()
temp = test_str.split(delim)
res = []
 
# using loop + eval() to convert to
# required result
for ele in temp:
  res.append(eval(ele))
 
# printing result
print("List after conversion : " + str(res))


Output

The original string is : 6#2#9#[3, 5, 6]#(7, 8)#8#4#10
List after conversion : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10]

Time complexity:O(n), where n is the number of elements in the input string ‘test_str’.
Auxiliary space: O(n), as it creates a temporary list ‘temp’ of size n, and a result list ‘res’ of size n.

Method #2 : Using eval() + split() + list comprehension

This is yet another way in which this task can be performed. In this, we perform the similar task as the above method. The only difference being that entire logic is encapsulated as one liner using list comprehension.

Python3




# Python3 code to demonstrate working of
# Convert delimiter separated Mixed String to valid List
# Using eval() + split() + list comprehension
 
# initializing string
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
 
# printing original string
print("The original string is : " + str(test_str))
 
# initializing delim
delim = "#"
 
# encapsulating entire result in list comprehension
res = [eval(ele) for ele in test_str.split(delim)]
 
# printing result
print("List after conversion : " + str(res))


Output

The original string is : 6#2#9#[3, 5, 6]#(7, 8)#8#4#10
List after conversion : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10]

Time complexity:O(n), where n is the number of elements in the input string ‘test_str’.
Auxiliary space: O(n), as it creates a temporary list ‘temp’ of size n, and a result list ‘res’ of size n.

Method #3: Using Regex and eval

This code splits the input string test_str using the delimiter specified by delim. It uses a regular expression to split the string only at positions where the delimiter is not inside a bracketed expression (either […] or (…)).

For each split element, it applies the eval() function to evaluate the expression as either a list or a tuple. The resulting list is stored in the res variable and printed at the end.

Python3




import re
 
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
delim = "#"
 
res = [eval(s) for s in re.split(delim + "(?![^\[]*\])(?![^(]*\))", test_str)]
print("List after conversion : " + str(res))
#This code is contributed by Vinay Pinjala.


Output

List after conversion : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10]

Time complexity: O(n), where n is the length of the input string. The split() method and the loop that follows both have a linear time complexity of O(n), where n is the length of the input string.
Auxiliary space: O(n), where n is the length of the input string. This is because the list ‘res’ is created to store the converted elements of the input string, and its size can grow up to n if all the characters in the input string need to be stored as separate elements in the list. Additionally, the ‘delim’ variable is stored, which takes constant space.

Method #4: Using str.split() and str.strip() without eval()

Uses str.split() and str.strip() to split the input string into individual elements and remove any leading/trailing whitespace, without using eval().

Python3




# Python3 code to demonstrate working of
# Convert delimiter separated Mixed String to valid List
# Using split() and strip()
 
# initializing string
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
 
# printing original string
print("The original string is : " + str(test_str))
 
# initializing delim
delim = "#"
 
# split string into elements and strip leading/trailing whitespace
elements = [e.strip() for e in test_str.split(delim)]
 
# convert elements to appropriate types
res = []
for e in elements:
    if e.startswith('[') or e.startswith('('):
        res.append(eval(e))
    else:
        res.append(int(e))
 
# printing result
print("List after conversion : " + str(res))


Output

The original string is : 6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10
List after conversion : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10]

Time complexity: O(n), where n is the length of the input string. 
Auxiliary space: O(n), where n is the length of the input string.

Method#5: Using Recursive method.

Algorithm:

  1. Define a recursive function convert_string_to_list that takes in the input string and delimiter as arguments.
  2. In the function, check if the delimiter is present in the input string. If not, return the input string after stripping any leading/trailing whitespaces.
  3. If the delimiter is present, split the input string based on the delimiter.
  4. Traverse through each substring and recursively call the convert_string_to_list function with the substring and delimiter as arguments.
  5. Append the result of the recursive call to a list.
  6. Return the list.
  7. Call the convert_string_to_list function with the input string and delimiter as arguments.
  8. Print the result.

Python3




def convert_string_to_list(s, delim):
    if delim not in s:
        # base case: if delimiter not found, return the value as-is
        return s.strip()
     
    # recursive case: split the string and recursively process each substring
    temp = s.split(delim)
    res = []
    for ele in temp:
        res.append(eval(convert_string_to_list(ele, delim)))
    return res
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
delim = "#"
print("The original string is : " + str(test_str))
res = convert_string_to_list(test_str, delim)
print("List after conversion : " + str(res))


Output

The original string is : 6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10
List after conversion : [6, 2, 9, [3, 5, 6], (7, 8), 8, 4, 10]

Time complexity

Time complexity of the split() function is O(n), where n is the length of the input string.
Time complexity of the for loop to traverse through each substring is also O(n), where n is the length of the input string.
In the worst case scenario, the input string may have all elements enclosed in brackets, resulting in a recursive call for each element. In that case, the function will be called a total of O(n) times, where n is the length of the input string.
Time complexity of the strip() function is O(k), where k is the length of the input string after stripping any leading/trailing whitespaces.

space complexity 
Space complexity of the list to store the results is O(n), where n is the length of the input string.
In the worst case scenario, the function call stack may contain O(n) frames, where n is the length of the input string.
Therefore, the overall time complexity is O(n^2) and the space complexity is O(n).

Method 5: Use the Python built-in function reduce() from the functools module. 

Step-by-step approach:

  • Import the reduce function from the functools module.
  • Define a helper function process_element() that takes two arguments: a list of elements lst and a delimiter d. The function checks if the delimiter is in the first element of the list, if not, it returns the element stripped of whitespace. If the delimiter is in the first element, the function recursively calls itself on the remaining elements of the list, concatenates the result with the first element (stripped of whitespace), and evaluates the resulting string with eval().
  • Define the convert_string_to_list() function that takes two arguments: a string s and a delimiter delim. The function splits the string into a list of elements using the delimiter, applies the process_element() function to each element using reduce(), and returns the resulting list.
  • Call the convert_string_to_list() function on the given test_str and delimiter delim.

Below is the implementation of the above approach:

Python3




from functools import reduce
 
def process_element(lst, d):
    if d not in lst[0]:
        return lst[0].strip()
    else:
        return eval(process_element(lst[1:], d)) + lst[0].strip()
 
def convert_string_to_list(s, delim):
    elements = s.split(delim)
    return reduce(lambda acc, e: acc + [process_element([e], delim)], elements, [])
 
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
delim = "#"
print("The original string is : " + str(test_str))
res = convert_string_to_list(test_str, delim)
print("List after conversion : " + str(res))


Output

The original string is : 6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10
List after conversion : ['6', '2', '9', '[3, 5, 6]', '(7, 8)', '8', '4', '10']

Time complexity: O(n^2), where n is the length of the input string s. 
Auxiliary space: O(n^2) as well, due to the recursive calls of the process_element() function that build up a new string to evaluate for each element of the list.

Method 6: Using numpy:

  1. Import numpy as np.
  2. Define the convert_string_to_list() function.
  3. Check if the delimiter is present in the string. If it’s not present, return the stripped string as is.
  4. If the delimiter is present, split the string into a list of substrings using the delimiter.
  5. Create an empty list res.
  6. For each substring, recursively call the convert_string_to_list() function and append the result to res.
  7. Convert res to a numpy array.
  8. Return the resulting numpy array.
  9. Define the test_str and delim variables.
  10. Call the convert_string_to_list() function with test_str and delim.
  11. Print the original string and the resulting numpy array.

Python3




import numpy as np
 
def convert_string_to_list(s, delim):
    if delim not in s:
        # base case: if delimiter not found, return the value as-is
        return s.strip()
     
    # recursive case: split the string and recursively process each substring
    temp = s.split(delim)
    res = []
    for ele in temp:
        res.append(np.array(convert_string_to_list(ele, delim)))
    return np.array(res)
 
test_str = "6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10"
delim = "#"
print("The original string is : " + str(test_str))
res = convert_string_to_list(test_str, delim)
print("List after conversion : " + str(res))
#This code is contributed by Jyothi pinjala.


Output:
The original string is : 6# 2# 9#[3, 5, 6]#(7, 8)# 8# 4# 10
List after conversion : ['6' '2' '9' '[3, 5, 6]' '(7, 8)' '8' '4' '10']

The time complexity of the convert_string_to_list() function using numpy is proportional to the length of the input string and the depth of the nested lists/tuples. In the worst-case scenario, where the input string contains nested lists/tuples of maximum depth, the time complexity is O(d * n * log n).

The auxiliary space is also proportional to the depth of the nested lists/tuples. In the worst-case scenario, where the input string contains nested lists/tuples of maximum depth, the space complexity is O(d * n * log n).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads