Stack Overflow Asked by Zhengrong on January 9, 2021
How can I regroup ‘sublists’ in a list with Python? For example, I want to regroup the following list:
[[0, 3], [1, 3], [1, 2], [1, 2], [0, 1], [0, 3]]
.
I want [0, 1] to be grouped with [2, 3]; [0, 2] with [1, 3]; [0, 3] with [1, 2], and left all the rest "coordinates" as single tuple. For example, in this case, I want
the output be:
[[[0, 3], [1, 2]], [[0, 3], [1, 2]], [0, 1], [1, 3]]
.
(The last two tuples here are "rest")
Is there a way I can achieve this goal? Thanks!!
Since the entries are only 0, 1, 2, 3 and the values are unique in every tuple, it means that the sum of the tuple can be generated by only one pair, except for 3, I mean: [0, 1] is the only tuple wich the sum of values return 1, by the same way [0, 2] is the only one to return 2, but [0,3] and [1,2] return 3, so them require to check if it is a tuple containing one specific value, such as 3
a = [[0, 3], [1, 3], [1, 2], [1, 2], [0, 1], [0, 3]]
b = []
c = []
d_03 = []
d_12 = []
e = []
f = []
list_of_pairs = []
for tuples in a:
if sum(tuples) == 1:
b.append(tuples)
elif sum(tuples) == 2:
c.append(tuples)
elif sum(tuples) == 4:
e.append(tuples)
elif sum(tuples) == 5:
f.append(tuples)
#testing if there is a 3 in that tuple as suggested above
elif sum(tuples) == 3 and 3 in tuples:
d_03.append(tuples)
else:
d_12.append(tuples)
#one way to figure out the perfect range would be compare the len of the lists that match and use the smaller one, so you don not need the else statement
for i in range(5):
#compare len with i+1 because python starts counting from 0
#if there is any element in those lists, their len will be bigger than 0
if len(b) >= i+1 and len(f) >= i+1:
#b have [0, 1] only as tuples
#f have [2, 3] only as tuples
#so when you append one after the other, they will always match
list_of_pairs.append(b[i])
list_of_pairs.append(f[i])
#pop it so at the end will only be in those lists the ones wich don't have their pair
b.pop(i)
f.pop(i)
#insert blank spaces just so you do not modify the indexes of any elements in the list
b.insert(i-1, '')
f.insert(i-1, '')
else:
#break it because if you run the conditional above it will return IndexError
#the following i values would also return this error
break
for i in range(5):
#same principle for c and e
#and after for d
if len(c) >= i+1 and len(e) >= i+1:
list_of_pairs.append(c[i])
list_of_pairs.append(e[i])
c.pop(i)
e.pop(i)
c.insert(i-1, '')
e.insert(i-1, '')
else:
break
for i in range(5):
if len(d_12) >= i+1 and len(d_03) >= i+1:
list_of_pairs.append(d_03[i])
list_of_pairs.append(d_12[i])
d_12.pop(i)
d_03.pop(i)
d_12.insert(i-1, '')
d_03.insert(i-1, '')
else:
break
#this final list must have the pairs and also the rest
final_list = []
#append the pairs so it will be presented first and as a list inside the final list
final_list.append(list_of_pairs)
#extend by all the previous lists except for list of pairs and a
#this will put any rest in the final list as separate therms from the pairs
final_list.extend(b)
final_list.extend(c)
final_list.extend(d_03)
final_list.extend(d_12)
final_list.extend(e)
final_list.extend(f)
#now the final list might have some '' as rest
#so you can loop through it removing them
while '' in final_list:
final_list.remove('')
print(final_list)
This is the output:
[[[0, 3], [1, 2], [0, 3], [1, 2]], [0, 1], [1, 3]]
Correct answer by Voz bonita on January 9, 2021
Assuming you have a list of lists (like in the example, and not actual tuples):
problem = [[0, 3], [1, 3], [1, 2], [1, 2], [0, 1], [0, 3]]
You want to pair these pairs so that each pair contains each of the values in (0, 1, 2, 3)
exactly once?
target = [0, 1, 2, 3]
And all the pairs that cannot be matched remain by themselves? This is one way of doing it:
answer = []
while problem:
# take the first element from problem
x1 = problem.pop()
# construct what the paired element should look like
x2 = [x for x in target if x not in x1]
try:
# attempt to remove it from problem
problem.remove(x2)
# if the remove succeeds, both x1 and x2 have now been removed, add the pair
answer.append([x1, x2])
except ValueError:
# when trying to remove a non-existent value, a ValueError is raised
# in that case, there is no matching pair, just add a single
answer.append(x1)
That's assuming:
target
target
problem
is modified during the processPut together:
problem = [[0, 3], [1, 3], [1, 2], [1, 2], [0, 1], [0, 3]]
target = [0, 1, 2, 3]
answer = []
while problem:
x1 = problem.pop()
x2 = [x for x in target if x not in x1]
try:
problem.remove(x2)
answer.append([x1, x2])
except ValueError:
answer.append(x1)
print(answer)
Result:
[[[0, 3], [1, 2]], [0, 1], [[1, 2], [0, 3]], [1, 3]]
Answered by Grismar on January 9, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP