0

I have a master list:

l = ['gala_apple', 'gala_lime', 'fuji_apple', 'fuji_lime']

Through some manipulation, I end up with a variant of l:

r = [
    'fuji_apple_1',
    'fuji_apple_2',
    'fuji_lime_1',
    'fuji_lime_2',
    'gala_apple_1',
    'gala_apple_2',
    'gala_apple_3',
    'gala_lime_1',
    'gala_lime_2',
    'gala_lime_3',
]

Using the master list l as a reference, I want the list r to be ordered like:

r = [
    'gala_apple_1',
    'gala_lime_1',
    'gala_apple_2',
    'gala_lime_2',
    'gala_apple_3',
    'gala_lime_3',
    'fuji_apple_1',
    'fuji_lime_1',
    'fuji_apple_2',
    'fuji_lime_2',
]

I.e. (gala_apple_X, gala_lime_X, gala_apple_Y, gala_lime_Y, ...), (fuji_apple_X, fuji_lime_X, fuji_apple_Y, fuji_lime_Y, ...)

1
  • 2
    Why should gala_lime_1 come before gala_apple_2? In the master list, gala_apple comes before gala_lime. Commented Jan 29, 2023 at 1:51

2 Answers 2

2

First use l to derive sort orders for the type (gala, fuji, etc) and fruit (apple, lime, etc):

>>> taxonomy = {}
>>> for x in l:
...     t, f = x.split("_")
...     taxonomy.setdefault(t, []).append(f)
... 
>>> type_order = {t: i for i, t in enumerate(taxonomy)}
>>> fruit_orders = {tuple(v) for v in taxonomy.values()}
>>> assert len(fruit_orders) == 1  
>>> fruit_order = {t: i for i, t in enumerate(fruit_orders.pop())}

That gives us:

>>> type_order
{'gala': 0, 'fuji': 1}
>>> fruit_order
{'apple': 0, 'lime': 1}

Then use that to define a sort key function which sorts first on type (the first field), then on number (the third field), then on fruit (the second field), using the established sort order for type and fruit, and numeric sort order for the number:

>>> def sort_key(x):
...     t, f, n = x.split("_")
...     return type_order[t], int(n), fruit_order[f]
... 

Then you can use that key to sort r:

>>> print(*sorted(r, key=sort_key), sep='\n')
gala_apple_1
gala_lime_1
gala_apple_2
gala_lime_2
gala_apple_3
gala_lime_3
fuji_apple_1
fuji_lime_1
fuji_apple_2
fuji_lime_2
Sign up to request clarification or add additional context in comments.

Comments

1

This works, but for scaling to more variables (e.g. gala_grape, gala_pear), you need to change the for-loop and, in general, the algorithm isn't very efficient.

r2 = []
for apple, lime in zip(l[0::2], l[1::2]):
    for i in range(len(r)):
        a_i = f'{apple}_{i}'
        if a_i in r:
            r2.extend([a_i, f'{lime}_{i}'])
print(r2)

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.