2

Input:

I have this ordered list.

[[1, 'A'], [1, 'B'],[1, 'D'], [2, 'A'],[2,'D'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

Desired output

[[1,['A','B','D']],[2, ['A','D']], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

Since the first item of those two sublists are same.

Also can i convert into a dictionary with a key and those values pair. Like

{1:['A','B','D'],2:['A','D'],3:['C']}

What is the easiest and simplest way to do this?

4
  • is input list ordered Commented Jun 11, 2017 at 2:06
  • 1
    What if there were a [1, 'C'] at the end of your outer list? Should that be grouped with the first two or not? This question is a bit underspecified. Commented Jun 11, 2017 at 2:06
  • I have specified it a bit more clear now take a loot @Serge Commented Jun 11, 2017 at 2:12
  • Well you alot of very good, varying responses. Commented Jun 11, 2017 at 2:37

8 Answers 8

3

If the data is ordered, then itertools.groupby is a good approach:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> data = [[1, 'A'], [1, 'B'], [2, 'A'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]
>>> final_data = []
>>> final_data = []
>>> for k, g in groupby(data, itemgetter(0)):
...     group = list(g)
...     if len(group) == 1:
...         final_data.append(group[0])
...     else:
...         final_data.append([k, [sub[1] for sub in group]])
...
>>> final_data
[[1, ['A', 'B']], [2, 'A'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]
>>>

If you want the results in a dictionary, that is even easier:

>>> grouped_dict = {}
>>> for num, letter in data:
...     grouped_dict.setdefault(num, []).append(letter)
...
>>> grouped_dict
{1: ['A', 'B'], 2: ['A'], 3: ['C'], 4: ['D'], 5: ['B'], 6: ['D']}
>>>
Sign up to request clarification or add additional context in comments.

Comments

2

You can create the dictionary directly from the input.

from collections import defaultdict

input = [[1, 'A'], [1, 'B'],[1, 'D'], [2, 'A'],[2,'D'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

d = defaultdict(list)
for el in input: d[el[0]].append(el[1])

The output of d will be:

{1: ['A', 'B', 'D'], 2: ['A', 'D'], 3: ['C'], 4: ['D'], 5: ['B'], 6: ['D']}

Comments

2

If the order is not important, and you want dictionary anyway:

import collections

your_list = [[1,'A'], [1,'B'], [1,'D'], [2,'A'], [2,'D'], [3,'C'], [4,'D'], [5,'B'], [6,'D']]

result = collections.defaultdict(list)
for k, v in your_list:
    result[k].append(v)

# {1: ['A', 'B', 'D'], 2: ['A', 'D'], 3: ['C'], 4: ['D'], 5: ['B'], 6: ['D']}

You can also do it without collections.defaultdict (probably at some performance penalty, in dependence of key frequency):

your_list = [[1,'A'], [1,'B'], [1,'D'], [2,'A'], [2,'D'], [3,'C'], [4,'D'], [5,'B'], [6,'D']]

result = {}
for k, v in your_list:
    result[k] = result.get(k, []) + [v]

# {1: ['A', 'B', 'D'], 2: ['A', 'D'], 3: ['C'], 4: ['D'], 5: ['B'], 6: ['D']}

Comments

2

You can use groupby from itertools module like this example:

a = [[1, 'A'], [1, 'B'],[1, 'D'], [2, 'A'],[2,'D'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

final = []
for k, v in groupby(sorted(a, key=lambda x: x[0]), lambda x: x[0]):
        bb = list(v)
        if len(bb) > 1:
            final.append([k, [j for _, j in bb]])
        else:
            final.append([k, bb[0][1]])

# OR:
# Within a list comprehension
# final = [[k, [j[1] for j in list(v)]] for k, v in groupby(sorted(a, key=lambda x: x[0]), lambda x: x[0])]

print(final)

Output:

[[1, ['A', 'B', 'D']], 
[2, ['A', 'D']],
[3, 'C'], 
[4, 'D'], 
[5, 'B'], 
[6, 'D']]

Then to convert the final list into a dict you can do:

final_dict = {k:v if isinstance(v, list) else [v] for k, v in final}
print(final_dict)

Output:

{1: ['A', 'B', 'D'], 2: ['A', 'D'], 3: ['C'], 4: ['D'], 5: ['B'], 6: ['D']}}

Comments

2

I found better do the opposite, instead of make a list and then a dictionary I made dictionary and then a list.

Input:

in_list = [[1, 'A'], [1, 'B'],[1, 'D'], [2, 'A'],[2,'D'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

Code:

mydict = {}
for sublist in in_list:
    if sublist[0] in mydict.keys():
        mydict[sublist[0]] = [*mydict[sublist[0]],sublist[1]]
    else:
        mydict[sublist[0]] = sublist[1]

Output:

>>> mydict
{1: ['A', 'B', 'D'], 2: ['A', 'D'], 3: 'C', 4: 'D', 5: 'B', 6: 'D'}

Make an easy list with the dictionary:

mylist = list(mydict.items())

Output:

>>> mylist
[(1, ['A', 'B', 'D']), (2, ['A', 'D']), (3, 'C'), (4, 'D'), (5, 'B'), (6, 'D')]

Make another list with the dictionary:

mylist = = [[k,v] for k,v in mydict.items()]

Same as:

mylist = []
for key, value in mydict.items():

Output:

>>> mylist
[[1, ['A', 'B', 'D']], [2, ['A', 'D']], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

Comments

1
in_list
out_list = []
sublist = []
i = 0
for l in in_list:
    if l[0] != i:
        i = l[0]
        sublist = []
        out_list.append([i, sublist])
    sublist.append(l[1])
dico = dict( out_list)

Comments

0

In the python documentation example, https://docs.python.org/2/library/collections.html#defaultdict-examples they used solved same problems in your post.

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

then I voted an answer with defaultdict.

Comments

0

dic = {} res_lst = [] lst = [[1, 'A'], [1, 'B'],[1, 'D'], [2, 'A'],[2,'D'], [3, 'C'], [4, 'D'], [5, 'B'], [6, 'D']]

convert into list pair

for lst_item in lst:
    if lst_item[0] in dic:
        for item in lst_item[1:]:
            dic[lst_item[0]].append(item)
    else:
        dic[lst_item[0]] = lst_item[1:]

convert into key value pair

for item in dic:
    lst1 = []
    lst1.append(item)
    if(len(dic[item]) == 1):
        lst1.append(dic[item][0])
    else:
        lst1.append(dic[item])
    res_lst.append(lst1)
print(res_lst)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.