0

I have a list of lists in the following format:

[['Sarah', '12', 'Chocolate'],
 ['Anders', '11', 'Vanilla'],
 ['Sarah', '13', 'Strawberry'],
 ['John', '11', 'None'],
 # ...
]

And I want to group the sublists as follows:

[['Sarah', '12', 'Chocolate', '13', 'Strawberry'],
 ['Anders', '11', 'Vanilla'],
 ['John', '11', 'None'],
 # ...
]

Where I group by the first item of the sublists and order by the second (so Sarahs with age 12 come before Sarahs with age 13).

How to do this?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
cprogrammer
  • 91
  • 2
  • 5

3 Answers3

2

You didn't show any code, so I won't give a complete solution.

One good data structure would be to use a dict, with names as keys and a list of tuples as values:

data =[['Sarah', '12', 'Chocolate'],
    ['Anders', '11', 'Vanilla'],
    ['Sarah', '13', 'Strawberry'],
    ['John', '11', 'None']]

grouped = {}

for name, x, y in data:
    grouped.setdefault(name, []).append((x,y))

print(grouped)
# {'Sarah': [('12', 'Chocolate'), ('13', 'Strawberry')], 'Anders': [('11', 'Vanilla')], 'John': [('11', 'None')]}

You'd just need to sort the values.

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • Rather than use `not dict.get(key)`, use `key not in dict`. And for adding a list, instead of `if : ... else: ...` you can use `dict.setdefault(key, []).append(...)`. – Martijn Pieters Oct 09 '17 at 09:20
  • @MartijnPieters: Excellent comment, thanks. You're also correct about `setdefault`. Since OP didn't show any code, I didn't want to use `defaultdict`, `groupby` or `dict.setdefault` in order to keep the example as simple as possible. – Eric Duminil Oct 09 '17 at 10:14
  • I don't see why `setdefault` is not simple. If you are going to answer, use best practices. Why dumb things down? – Martijn Pieters Oct 09 '17 at 10:15
  • @MartijnPieters: Modified. What bothers me about about `dict.setdefault` is that it's used as a getter, which can be surpising. – Eric Duminil Oct 09 '17 at 10:20
  • It's no more surprising than using `defaultdict`, in my opinion. – Martijn Pieters Oct 09 '17 at 10:22
  • @MartijnPieters: I probably shouldn't argue with you about Python :). But here goes : `d = defaultdict(list); d['not_here']` It's pretty clear that it returns `[]`. Instead, knowing that assignments return `None` in Python, I'd expect `dict.setdefault('not_here', [])` to also return `None`. – Eric Duminil Oct 09 '17 at 10:34
  • Assignments don't return anything in Python, because assignments are statements, not expressions. `dict.setdefault(...)` is an expression, so returns *something*, always. It is documented as returning the current value for the key, using the second value as a default if there is no such key (setting the key-value pair in the process). – Martijn Pieters Oct 09 '17 at 11:55
  • @MartijnPieters: Yes, it's documented. All I'm saying is that the method name isn't very consistent with its behaviour. – Eric Duminil Oct 09 '17 at 11:59
0

A few possible solutions jump to mind, but here's one. Read through the comments and feel free to ask questions:

from collections import defaultdict

l = [
        ['Sarah', '12', 'Chocolate'],
        ['Anders', '11', 'Vanilla'],
        ['Sarah', '13', 'Strawberry'],
        ['John', '11', 'None'],
]

d = defaultdict(list)

for entry in l:
    d[entry[0]].append(entry[1:])

# Here d looks something like this:
# {'Sarah': [['12', 'Chocolate'], ['13', 'Strawberry']], ...}

result = [
    # 1. Sort the list by the first element of each sublist (parsed as an int).
    # 2. Flatten the result as in https://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python/952952#952952.
    # 3. Prepend the key (name).
    [k] + [item for sublist in sorted(v, key=lambda x: int(x[0])) for item in sublist]
    for k,v in d.items()
]

print(result)

# Output: [['Sarah', '12', 'Chocolate', '13', 'Strawberry'], ['Anders', '11', 'Vanilla'], ['John', '11', 'None']]
user94559
  • 59,196
  • 6
  • 103
  • 103
0

You can try this :

import itertools


list_1=[['Sarah', '12', 'Chocolate'],
       ['Anders', '11', 'Vanilla'],
       ['Sarah', '13', 'Strawberry'],
       ['John', '11', 'None']]

repeated_list=[]
unique_list=[]
for item_1,item_2 in itertools.combinations(list_1,2):
    if item_1[0]==item_2[0]:
        repeated_list.append(item_1+item_2)

    else:

        for item_3 in repeated_list:
            if item_2[0] not in item_3:
                if item_2 not in unique_list:
                    unique_list.append(item_2)

            elif item_1[0] not in item_3:
                if item_1 not in unique_list:
                    unique_list.append(item_1)


print(unique_list+repeated_list)

Output:

[['John', '11', 'None'], ['Anders', '11', 'Vanilla'], ['Sarah', '12', 'Chocolate', 'Sarah', '13', 'Strawberry']]
Aaditya Ura
  • 12,007
  • 7
  • 50
  • 88