Sorting lines by keyword and group results

Viewed 58

I want to sort links like in desired output, but I have no idea how to change my code

So, how to change code to get my desired output?

Thanks in advance for any help

Code:

def my_sort(line):
    social_folders = {'engine': 1,
                    'wormix_mm': 2,
                    'wormix_ok': 3}
    line_fields = line.strip().split("/")
    social = line_fields[3]
    print(line_fields[3])
    return social_folders[social]

numbers = 'First', 'Second', 'Third', 'Fourth'
with open('./testsort.txt') as testsortf, \
     open('./test_out999.txt', "w") as test_out:
    contents = testsortf.readlines()
    contents[-1] = f'{contents[-1]}\n'
    contents.sort(key=my_sort)
    for i, line in enumerate(contents):
        test_out.write(f'{numbers[i]}:\n{line}')
        if i+1 < len(contents):
            test_out.write('\n')

My inputs from .txt file:

https://markus.rmart.ru/engine/preloader/somefold
https://markus.rmart.ru/wormix_ok/preloader/somefold3
https://markus.rmart.ru/engine/preloader/somefold3
https://markus.rmart.ru/engine/preloader/somefold1
https://markus.rmart.ru/wormix_ok/preloader/somefold4
https://markus.rmart.ru/wormix_mm/preloader/somefold2
https://markus.rmart.ru/wormix_mm/preloader/somefold1
https://markus.rmart.ru/engine/preloader/somefold2
https://markus.rmart.ru/engine/preloader/somefold5
https://markus.rmart.ru/wormix_mm/preloader/somefold5
https://markus.rmart.ru/wormix_ok/preloader/somefold1

So, inputs without any sorting

Desired output:

First:
https://markus.rmart.ru/engine/preloader/somefold
https://markus.rmart.ru/engine/preloader/somefold3
https://markus.rmart.ru/engine/preloader/somefold1
https://markus.rmart.ru/engine/preloader/somefold2
https://markus.rmart.ru/engine/preloader/somefold5

Second:
https://markus.rmart.ru/wormix_mm/preloader/somefold2
https://markus.rmart.ru/wormix_mm/preloader/somefold1
https://markus.rmart.ru/wormix_mm/preloader/somefold5

Third:
https://markus.rmart.ru/wormix_ok/preloader/somefold1
https://markus.rmart.ru/wormix_ok/preloader/somefold4
https://markus.rmart.ru/wormix_ok/preloader/somefold3

Now output:

First:
https://markus.rmart.ru/engine/preloader/somefold

Second:
https://markus.rmart.ru/engine/preloader/somefold1

Third:
https://markus.rmart.ru/engine/preloader/somefold3

Fourth:
https://markus.rmart.ru/engine/preloader/somefoldtest
2 Answers

Try this code (I commented what I did, inside the code).

def my_sort(conts):
    social_folders = {'engine': 1, 'wormix_mm': 2, 'wormix_ok': 3}
    line_fields = conts.strip().split("/")
    social = line_fields[3]
    return social_folders[social]


# I didn't know what is the differences between First and second section.
# So I put them together. You can handle that yourself.
numbers = 'First', 'Second', 'Third'#, 'Fourth'
folds = ['engine', 'wormix_mm', 'wormix_ok']
with open('./testsort.txt') as testsortf, open('./test_out999.txt', "w") as test_out:
    contents = testsortf.readlines()
    contents[-1] = f'{contents[-1]}\n'
    contents.sort(key=my_sort)
    # It needs 2 for loops
    for k, fold in enumerate(numbers):
        # Put enter before every category, except the first one
        if k != 0:
            test_out.write(f'\n')
        # Put the label of each category
        test_out.write(f'{numbers[k]}:\n')
        for i, line in enumerate(contents):
            # Put the right label in each category
            if line.strip().split("/")[3] == folds[k]:
                test_out.write(f'{line}')

itertools.groupby() from the standard library will cluster the list of links the way you want, but it requires a bit of set up. Specifically, in addition to a sorted iterable of links, it needs to know what part of the link string to group by. For that, something like a regular expression that isolates the key part of the link is needed.

Example:

import re
from itertools import groupby

sorted_links = sorted([
    "https://markus.rmart.ru/engine/preloader/somefold",
    "https://markus.rmart.ru/wormix_ok/preloader/somefold3",
    "https://markus.rmart.ru/engine/preloader/somefold3",
    "https://markus.rmart.ru/engine/preloader/somefold1",
    "https://markus.rmart.ru/wormix_ok/preloader/somefold4",
    "https://markus.rmart.ru/wormix_mm/preloader/somefold2",
    "https://markus.rmart.ru/wormix_mm/preloader/somefold1",
    "https://markus.rmart.ru/engine/preloader/somefold2",
    "https://markus.rmart.ru/engine/preloader/somefold5",
    "https://markus.rmart.ru/wormix_mm/preloader/somefold5",
    "https://markus.rmart.ru/wormix_ok/preloader/somefold1",
])

# Finds the category part of the path that follows the domain name (e.g., "engine")
category = re.compile(r"https.*\.[a-z]{2,3}\/([^\/]*)")

for _, group in groupby(sorted_links, lambda url: category.search(url).group(1)):
    for url in group:
        print(url)
    print()

Output:

https://markus.rmart.ru/engine/preloader/somefold
https://markus.rmart.ru/engine/preloader/somefold1
https://markus.rmart.ru/engine/preloader/somefold2
https://markus.rmart.ru/engine/preloader/somefold3
https://markus.rmart.ru/engine/preloader/somefold5

https://markus.rmart.ru/wormix_mm/preloader/somefold1
https://markus.rmart.ru/wormix_mm/preloader/somefold2
https://markus.rmart.ru/wormix_mm/preloader/somefold5

https://markus.rmart.ru/wormix_ok/preloader/somefold1
https://markus.rmart.ru/wormix_ok/preloader/somefold3
https://markus.rmart.ru/wormix_ok/preloader/somefold4
Related