3

I have a list of lists as follows:

mylist=[[a,b],[a,c],[b,c],[c,d],[d,e],[e,c]]

What I would like to do is iterate through mylist and produce a new list like this:

result=[ [ [a,b],[c,d] ] , [ [a,c],[d,e] ] , [ [b,c] ], [ [e,c] ] ]

In other words, make a list of lists, where each list contains unique combinations of entries of the initial list, so that a letter is not present twice in each entry of result list. Also each time an entry is added to result, we abstract it's sub elements from the set of available combinations of the initial list. (I guess the given example makes it more clear than the explanation).

Pola
  • 143
  • 4
  • 15

5 Answers5

1

This should work for you:

mylist=[['a','b'],['a','c'],['b','c'],['c','d'],['d','e'],['e','c']]
final_res=[]
while(len(mylist)>0):
    res=[list(mylist[0])]
    mylist.remove(res[0])
    for l in mylist:
        if len(set(l) & set().union(*res))==0:
            res.append(l)
            mylist.remove(l)
    final_res.append(res)

output:

print final_res
>> [[['a', 'b'], ['c', 'd']], [['a', 'c'], ['d', 'e']], [['b', 'c']], [['e', 'c']]]
Binyamin Even
  • 3,318
  • 1
  • 18
  • 45
  • Both @Vivek Sable 's answer and this answer produce the correct result. I accepted the second answer since I believe it is more elegant. Thank you both for your quick responses! :) – Pola Mar 31 '17 at 09:08
  • sure. you can look it up here: http://stackoverflow.com/questions/2151517/pythonic-way-to-create-union-of-all-values-contained-in-multiple-lists – Binyamin Even Mar 31 '17 at 11:15
1

Code:

mylist=[['a','b'],['a','c'],['b','c'],['c','d'],['d','e'],['e','c']]
#- Get Length of mylist which is used in 2nd for loop to iterate items from next item to last item
len_mylist = len(mylist)
#- Final Result Will store in following variable.
output = []
#- this is Index of item which already present in Output List.
remove_index = []

# Iterate every item from mylist with his Index.
for i, item in enumerate(mylist):

    tmp = []
    #- Check item is already present in Remove List of not.
    if i in remove_index:
        continue

    #- Add index to Remove list and add item to tmp which is item in otput list.
    remove_index.append(i)
    tmp.append(item)
    #- Iterate from Next item to last item of mylist.
    for j in range(i+1, len_mylist):
        itemj = mylist[j]
        #- Set insert flag to True on which we are decide to insert item or not.
        inser_flag = True
        # Iterate on inner item 
        for tmp_item in tmp:
            #- Check next item letters already present or not.
            if tmp_item[0] in itemj or tmp_item[1] in itemj:
                inser_flag = False
                break
            #- Check item is already present in Remove List of not.
            if j in remove_index:
                inser_flag = False
                break

        #- Add item to inner item if Flag is True.
        if inser_flag:
            remove_index.append(j)
            tmp.append(itemj)
            break
    # append to Final Output
    output.append(tmp)

Output:

>>> output
[[['a', 'b'], ['c', 'd']], [['a', 'c'], ['d', 'e']], [['b', 'c']], [['e', 'c']]]
Vivek Sable
  • 9,938
  • 3
  • 40
  • 56
0

Maybe you can try to use zip:

mylist=[['a','b'],['a','c'],['b','c'],['c','d'],['d','e'],['e','c']]

print zip(mylist[:len(mylist)/2],mylist[len(mylist)/2:])

Result:

[(['a', 'b'], ['c', 'd']), (['a', 'c'], ['d', 'e']), (['b', 'c'], ['e', 'c'])]

If you want to iterate the result, just use for i in zip() or you can convert the tuple to list:

print [list(i) for i in zip(mylist[:len(mylist)/2],mylist[len(mylist)/2:])]

Output:

[[['a', 'b'], ['c', 'd']], [['a', 'c'], ['d', 'e']], [['b', 'c'], ['e', 'c']]]

Or just use a list comprehension:

print [[mylist[i],mylist[i+len(mylist)/2]] for i in range(len(mylist)/2)]
McGrady
  • 10,869
  • 13
  • 47
  • 69
0
base_list = [['a','b'],['a','c'],['b','c'],['c','d'],['d','e'],['e','c']]
list_len = len(base_list)
list1 = []
list2 = []
new_list = []
if list_len%2 == 0:
    list1 = base_list[:list_len/2]
    list2 = base_list[list_len/2:]
    for i, j in zip(list1,list2):
        new_list.append(i)
        new_list.append(j)
    print "new list=",new_list
else:
    list1 = base_list[:list_len-1/2]
    list2 = base_list[list_len-1/2:]
    list3 = base_list[-1:]
    for i, j in zip(list1,list2):
        new_list.append(i)
        new_list.append(j)
    new_list.append(list3)
    print "new list=",new_list

out:

new list= [['a', 'b'], ['c', 'd'], ['a', 'c'], ['d', 'e'], ['b', 'c'], ['e', 'c']]
Alpesh Valaki
  • 1,611
  • 1
  • 16
  • 36
0

This does the job :

myList=[['a','b'],['a','c'],['b','c'],['c','d'],['d','e'],['e','c']]
newList=[]


while len(myList) > 0:
    print 'my entry list' + str(myList)
    tmpList = []
    stop = 0
    toRemove = [0]
    i = 0
    alreadyUsed = []
    tmpList.append(myList[i])
    for j in range (len(myList[i])):
        alreadyUsed.append(myList[i][j])
    i+=1
    while stop != 1 :
        try :
            if myList[i][0] not in alreadyUsed and myList[i][1] not in alreadyUsed:
                tmpList.append(myList[i])
                print 'tmpList' + str(tmpList)
                for j in range (len(myList[i])):
                    alreadyUsed.append(myList[i][j])
                toRemove.append(i)
            i+=1
        except IndexError:
            print 'No more elements in the list'
            stop = 1
    newList.append(tmpList)
    while len(toRemove) > 0 :
        x = toRemove[-1]
        del myList[x]
        del toRemove[-1]


print newList 
Axel
  • 41
  • 1
  • 5