Reputation: 129
I have a nested list containing strings which I want to group based on the first element of a nested list. After grouping them, I then want to remove any duplicate first elements and convert the list to a simple string seperated by a semicolon.
What I have managed so far is to output the simple string as well as removing duplicate first elements. I did this by saving the first element of the list in a new empty list, and using the if/else statement to decide what to append to the new output list.
exampleinput = ["[['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'], ['1','2','5'],['1','7','8']]"]
def makestring(n):
str1 = ' '.join(n)
return str1
def transform(n):
first = []
output = []
for i in n:
if i[0] not in first:
output.append(makestring(i))
else:
string1 = makestring(i[1:])
output.append(string1)
first.append(i[0])
return output
for i in exampleinput:
print(transform(eval(i.strip())))
Example input:
[['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'],['1','2','5'],['1','7','8']]
Desired output:
['1 2 3 ; 4 6 ; 2 5 ; 7 8', '2 1 2', ' 3 4 2']
Actual output:
['1 2 3', '4 6', '2 1 2', '3 4 2, '2 5', '7 8']
Any thoughts? Thanks in advance!
Upvotes: 1
Views: 1366
Reputation: 92854
With itertools.groupby
function:
from itertools import groupby
inp_list = [['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'],['1','2','5'],['1','7','8']]
res = []
for k, g in groupby(sorted(inp_list, key=lambda x: x[0]), key=lambda x: x[0]):
item1, *rest = g
res.append('; '.join(map(' '.join, [item1] + [i[1:] for i in rest]))
if rest else ' '.join(item1))
print(res)
The output:
['1 2 3; 4 6; 2 5; 7 8', '2 1 2', '3 4 2']
Bonus solution with just using an auxiliary grouping dictionary:
inp_list = [['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'],['1','2','5'],['1','7','8']]
groups_dict = {}
for sub_l in inp_list:
if sub_l[0] not in groups_dict:
groups_dict[sub_l[0]] = ' '.join(sub_l)
else:
groups_dict[sub_l[0]] += '; ' + ' '.join(sub_l[1:])
res = list(groups_dict.values())
print(res) # ['1 2 3; 4 6; 2 5; 7 8', '2 1 2', '3 4 2']
Upvotes: 2
Reputation: 73
Instead of appending to string one you are appending to the output in the order which given. Here is the code I got to work:
exampleinput = ["[['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'], ['1','2','5'],['1','7','8']]"]
def makestring(i):
return "".join(i)
def main(i):
string1 = ""
first = ["1"] # for (123)
output = []
string1 += makestring(i[0])
for x in i[1:]:
if x[0] in first:
string1 += " ; "+makestring(x[1:])
else:
output.append(makestring(x))
first.append(x[0])
return [string1] + output
if __name__ == "__main__":
print(main(eval(exampleinput[0].strip())))
This returns the output: ['123 ; 46 ; 25 ; 78', '212', '342']
Upvotes: 0
Reputation: 1012
First I use the join method to create a list of strings
signal = [['1','2','3'],['1','4','6'],['2','1','2'],['3','4','2'],['1','2','5'],['1','7','8']]
my_list =[" ".join(x) for x in [y for y in signal] ]
then search list from end to start to the comparison the first character of that string is in other items if it's true and it's not same item and index of item greater than item that selected then removes it.
for i in range(len(my_list)-1,0,-1):
for j in my_list:
if my_list[i][0] == j[0] and my_list[i] != j and i > my_list.index(j):
my_list[i]= my_list[i][1:]
print(my_list)
output:
['1 2 3', ' 4 6', '2 1 2', '3 4 2', ' 2 5', ' 7 8']
Upvotes: 0