-1

Like I have this list, and I tried many things, but I ended up getting a type error. Is it even possible in Python?

Input = [3,1,0,4,1,[5,4,7]]

output = [0,1,1,3,4,[4,5,7]]

5
  • 3
    What happens if the nested list is in the middle of the list? I mean how should you compare a list to an integer? Commented Jul 20, 2022 at 16:47
  • Try looking at Is it possible to sort a list in ascending order in python. Commented Jul 20, 2022 at 16:57
  • 1
    what would happen with multiple lists? a = [3,1, [9, 4, 1],4,1,[5,4]] --> [1, 3, [1, 4, 9], 1, 4, [4, 5]]? Commented Jul 20, 2022 at 17:06
  • Please provide enough code so others can better understand or reproduce the problem. Commented Jul 20, 2022 at 17:15
  • Your question is underspecified. That is, it doesn't contain a clear definition of the expected behavior. Furthermore, you are expected to show us the solution(s) you have tried. Commented Aug 11, 2023 at 3:24

4 Answers 4

2

You can use itertools.groupby:

from itertools import groupby

def sorted_mixed(lst):
    output = []
    for k, g in groupby(lst, key=lambda x: isinstance(x, list)):
        if k: # if the group consists of lists
            output += [sorted(x) for x in g] # sort each list
        else: # if the group consists of others
            output += sorted(g)
    return output

print(sorted_mixed([3,1,0,4,1,[5,4,7]]))
# [0, 1, 1, 3, 4, [4, 5, 7]]
print(sorted_mixed([3,1,[9,4,1],4,1,[5,4]]))
# [1, 3, [1, 4, 9], 1, 4, [4, 5]]
print(sorted_mixed([[4,3],[2,1]]))
# [[3, 4], [1, 2]]
Sign up to request clarification or add additional context in comments.

1 Comment

What it expects to have this list: (sorted_mixed([3,1,[9,4,1],24,11,[5,4], 0]))
1

The items are sorted locally, not globally. For a different behavior more information should be given.

from itertools import groupby, chain

def local_ordering(lst): # depends on groupby & chain
    return list(chain.from_iterable([sorted(next(grp))] if gr_type is list else sorted(grp) for gr_type, grp in groupby(lst, key=type)))


def global_values_local_lists_ordering(lst): # depends on itertools.groupy
    # global for values, local for lists
    grps = {}
    only_numbers = []
    # group by type
    for i, (gr_type, grp) in enumerate(groupby(lst, key=type)):
        if gr_type == list:
            # sort nested list
            grps[i] = sorted(next(grp))
        else:
            # add grp size
            g = list(grp)
            grps[i] = len(g)
            only_numbers.extend(g)
    # in place sort
    only_numbers.sort()

    # final list
    out = []
    for v in grps.values():
        if isinstance(v, list):
            out.append(v)
        else:
            # iterate over group of numbers
            for i in range(v):
                out.append(only_numbers.pop(0))
    return out


def global_ordering(lst): # no imports needed
    # flat the list
    flat_list = []
    lists_info = {}
    for i, term in enumerate(lst):
        if isinstance(term, list):
            lists_info[i] = len(term)
            flat_list.extend(term)
        else:
            flat_list.append(term)
    # in-place sort
    flat_list.sort()

    # regrouping
    out = []
    index = 0
    while flat_list:
        if index in lists_info:
            step = lists_info.pop(index)
            out.append([flat_list.pop(0) for _ in range(step)])
        else:
            out.append(flat_list.pop(0))
        index += 1

    return out

Tests and (order) ambiguities:

Case from the question: every implementation has the same output

a = [3,1,0,4,1,[5,4,7]]
print(a)
print()
print(local_ordering(a))
print(global_values_local_lists_ordering(a))
print(global_ordering(a))

Output

[3, 1, 0, 4, 1, [5, 4, 7]]

[0, 1, 1, 3, 4, [4, 5, 7]]
[0, 1, 1, 3, 4, [4, 5, 7]]
[0, 1, 1, 3, 4, [4, 5, 7]]

With a different list with more sublists: each implementation behave differently, hence "order ambiguity"

a = [3,1, [9, 4, 1],4,1,[5,4]]
print(a)
print()
print(local_ordering(a))
print(global_values_local_lists_ordering(a))
print(global_ordering(a))

Output

[3, 1, [9, 4, 1], 4, 1, [5, 4]]

[1, 3, [1, 4, 9], 1, 4, [4, 5]]
[1, 1, [1, 4, 9], 3, 4, [4, 5]]
[1, 1, [1, 3, 4], 4, 4, [5, 9]]

Comments

0

You could also make use of NumPy arrays and masking. I assume that you want to preserve the position of the list inside the global list, but order all numbers of the global list.

First create a mask that differentiates list items that are numbers from list items that are list through Booleans. Then create a sorted list with the numbers, sort each inner list and place the inner list at the right position in the global list. np.dnenumerate is like enumerate for NumPy arrays.

lst = [3,1,0,4,1,[5,4,7]]
import numpy as np
arr = np.array(lst)

mask = np.array([True if type(i) != list else False for i in lst])
result = sorted(arr[mask])
for idx_lst, idx_mask in np.ndenumerate(np.where(mask==False)):
    result.insert(idx_mask, sorted(arr[~mask][idx_lst[1]]))

result:

[0, 1, 1, 3, 4, [4, 5, 7]]

Another example:

lst = [3,1, [9, 4, 1],4,1,[5,4]]

result:

[1, 1, [1, 4, 9], 3, 4, [4, 5]]

Comments

-2

There are many ways to solve it. As a beginner in Python, I solved it like this, but there are more elegant ways with list comprehension.

Input = [3, 1, 0, 4, 1, [5, 4, 7]]
new_list = []
for value in Input:
    if type(value) != list:
        new_list.append(value)
    else:
        for element in value:
            new_list.append(element)

print(f"This is the new list: {new_list}")
new_list.sort()
print(new_list)

3 Comments

This removes the elements from the nested list and puts them in the top level list
As I said, it's just one of many ways to do it.
No it isn't, because it's not the output OP wants

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.