Python Forum

Full Version: Sort sets by item values
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Good day!

In Python, a beginner, so I apologize in advance, if not correct, I will describe something.

There are set, for example:
{'permit tcp host 192.168.23.6 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 135', 'permit udp host 192.168.23.2 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.5 host 192.168.2.26 eq 49749', 'permit tcp host 192.168.23.4 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.2 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 445', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.7 host 192.168.2.31 eq 53', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.9 host 192.168.2.26 eq 49749', 'permit tcp host 192.168.23.7 host 192.168.2.32 eq 49670', 'permit udp host 192.168.23.5 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.7 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.9 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.6 host 192.168.2.23 eq 80', 'permit udp host 192.168.23.3 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 135', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 123', 'permit udp host 192.168.23.1 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.1 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.8 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 135', 'permit udp host 192.168.23.2 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.6 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.3 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.2 host 192.168.2.28 eq 445', 'permit tcp host 192.168.23.7 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.4 host 192.168.2.32 eq 88', 'permit udp host 192.168.23.9 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 88', 'permit udp host 192.168.23.8 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.8 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.2 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.6 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.1 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.2 host 192.168.2.26 eq 49749', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 135', 'permit tcp host 192.168.23.5 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 445', 'permit udp host 192.168.23.8 host 192.168.2.31 eq 53', 'permit tcp host 192.168.23.1 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.3 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.9 host 192.168.2.31 eq 53', 'permit tcp host 192.168.23.6 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.2 host 192.168.2.23 eq 8530', 'permit udp host 192.168.23.6 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.4 host 192.168.2.32 eq 389', 'permit udp host 192.168.23.1 host 192.168.2.31 eq 53', 'permit tcp host 192.168.23.7 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.5 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.1 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.4 host 192.168.2.31 eq 53', 'permit tcp host 192.168.23.5 host 192.168.2.28 eq 445', 'permit udp host 192.168.23.3 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.4 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 49670', 'permit tcp host 192.168.23.8 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.8 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.8 host 192.168.2.31 eq 49667', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 445', 'permit udp host 192.168.23.8 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.4 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.5 host 192.168.2.28 eq 135', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 49667', 'permit tcp host 192.168.23.7 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 49670', 'permit tcp host 192.168.23.9 host 192.168.2.23 eq 80', 'permit udp host 192.168.23.6 host 192.168.2.32 eq 53'}
I need to sort it by the values inside the elements. The output does not have to be set, just to display the result line by line.

For example, let's take 'permit udp host 192.168.23.6 host 192.168.2.32 eq 53'. You must first sort by 53, then by 192.168.2.32, then by 192.168.23.6. I do not even understand in which direction to move.

I thought of using split for separating each element and subsequent analysis, but it seems to me that it is very cumbersome and there must be some longer beautiful solution.
Using sorted with a key function to obtain the eq value

Edit: added 2nd and 3rd sorting, not sure if 2nd and 3rd sorting key is how you want it

values = {'permit tcp host 192.168.23.6 host 192.168.2.31 eq 445',
          'permit tcp host 192.168.23.5 host 192.168.2.31 eq 135',
          'permit udp host 192.168.23.2 host 192.168.2.32 eq 53',
          'permit tcp host 192.168.23.5 host 192.168.2.26 eq 49749',
          'permit tcp host 192.168.23.4 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.2 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.9 host 192.168.2.31 eq 445',
          'permit udp host 192.168.23.5 host 192.168.2.32 eq 53',
          'permit udp host 192.168.23.7 host 192.168.2.31 eq 53',
          'permit tcp host 192.168.23.5 host 192.168.2.32 eq 389',
          'permit tcp host 192.168.23.9 host 192.168.2.26 eq 49749',
          'permit tcp host 192.168.23.7 host 192.168.2.32 eq 49670',
          'permit udp host 192.168.23.5 host 192.168.2.31 eq 53',
          'permit udp host 192.168.23.7 host 192.168.2.32 eq 53',
          'permit udp host 192.168.23.9 host 192.168.2.32 eq 53',
          'permit tcp host 192.168.23.6 host 192.168.2.23 eq 80',
          'permit udp host 192.168.23.3 host 192.168.2.31 eq 53',
          'permit udp host 192.168.23.5 host 192.168.2.32 eq 389',
          'permit tcp host 192.168.23.9 host 192.168.2.31 eq 135',
          'permit udp host 192.168.23.5 host 192.168.2.32 eq 123',
          'permit udp host 192.168.23.1 host 192.168.2.32 eq 53',
          'permit tcp host 192.168.23.1 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.8 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.1 host 192.168.2.32 eq 135',
          'permit udp host 192.168.23.2 host 192.168.2.31 eq 53',
          'permit udp host 192.168.23.6 host 192.168.2.31 eq 389',
          'permit tcp host 192.168.23.3 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.2 host 192.168.2.28 eq 445',
          'permit tcp host 192.168.23.7 host 192.168.2.23 eq 8530',
          'permit tcp host 192.168.23.4 host 192.168.2.32 eq 88',
          'permit udp host 192.168.23.9 host 192.168.2.31 eq 389',
          'permit tcp host 192.168.23.5 host 192.168.2.31 eq 88',
          'permit udp host 192.168.23.8 host 192.168.2.31 eq 389',
          'permit udp host 192.168.23.8 host 192.168.2.32 eq 389',
          'permit tcp host 192.168.23.2 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.6 host 192.168.2.31 eq 389',
          'permit udp host 192.168.23.1 host 192.168.2.32 eq 389',
          'permit tcp host 192.168.23.2 host 192.168.2.26 eq 49749',
          'permit tcp host 192.168.23.5 host 192.168.2.32 eq 135',
          'permit tcp host 192.168.23.5 host 192.168.2.23 eq 8530',
          'permit tcp host 192.168.23.1 host 192.168.2.32 eq 445',
          'permit udp host 192.168.23.8 host 192.168.2.31 eq 53',
          'permit tcp host 192.168.23.1 host 192.168.2.23 eq 8530',
          'permit tcp host 192.168.23.3 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.9 host 192.168.2.31 eq 389',
          'permit udp host 192.168.23.9 host 192.168.2.31 eq 53',
          'permit tcp host 192.168.23.6 host 192.168.2.31 eq 135',
          'permit tcp host 192.168.23.2 host 192.168.2.23 eq 8530',
          'permit udp host 192.168.23.6 host 192.168.2.31 eq 53',
          'permit udp host 192.168.23.4 host 192.168.2.32 eq 389',
          'permit udp host 192.168.23.1 host 192.168.2.31 eq 53',
          'permit tcp host 192.168.23.7 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.4 host 192.168.2.31 eq 135',
          'permit tcp host 192.168.23.5 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.1 host 192.168.2.31 eq 445',
          'permit tcp host 192.168.23.5 host 192.168.2.31 eq 389',
          'permit udp host 192.168.23.4 host 192.168.2.31 eq 53',
          'permit tcp host 192.168.23.5 host 192.168.2.28 eq 445',
          'permit udp host 192.168.23.3 host 192.168.2.32 eq 53',
          'permit udp host 192.168.23.4 host 192.168.2.32 eq 53',
          'permit tcp host 192.168.23.5 host 192.168.2.32 eq 49670',
          'permit tcp host 192.168.23.8 host 192.168.2.31 eq 389',
          'permit tcp host 192.168.23.8 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.8 host 192.168.2.31 eq 49667',
          'permit tcp host 192.168.23.4 host 192.168.2.31 eq 445',
          'permit udp host 192.168.23.8 host 192.168.2.32 eq 53',
          'permit tcp host 192.168.23.5 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.4 host 192.168.2.32 eq 445',
          'permit tcp host 192.168.23.5 host 192.168.2.28 eq 135',
          'permit tcp host 192.168.23.4 host 192.168.2.31 eq 49667',
          'permit tcp host 192.168.23.7 host 192.168.2.23 eq 80',
          'permit tcp host 192.168.23.1 host 192.168.2.32 eq 49670',
          'permit tcp host 192.168.23.9 host 192.168.2.23 eq 80',
          'permit udp host 192.168.23.6 host 192.168.2.32 eq 53'}


def sort_key(item):
    rest, eq = item.split('eq')
    _, ip1, ip2 = rest.split('host')
    ip1 = tuple(int(i) for i in ip1.split('.'))
    ip2 = tuple(int(i) for i in ip2.split('.'))
    return int(eq), ip2, ip1

print(sort_key('permit udp host 192.168.23.6 host 192.168.2.32 eq 53'))

sorted_values = sorted(values, key=sort_key)
 
print(sorted_values)
Output:
(53, (192, 168, 2, 32), (192, 168, 23, 6)) ['permit udp host 192.168.23.1 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.2 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.3 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.4 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.5 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.6 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.7 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.8 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.9 host 192.168.2.31 eq 53', 'permit udp host 192.168.23.1 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.2 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.3 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.4 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.6 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.7 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.8 host 192.168.2.32 eq 53', 'permit udp host 192.168.23.9 host 192.168.2.32 eq 53', 'permit tcp host 192.168.23.1 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.2 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.3 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.4 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.5 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.6 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.7 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.8 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.9 host 192.168.2.23 eq 80', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 88', 'permit tcp host 192.168.23.4 host 192.168.2.32 eq 88', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 123', 'permit tcp host 192.168.23.5 host 192.168.2.28 eq 135', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.6 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 135', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 135', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 135', 'permit tcp host 192.168.23.5 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.6 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.6 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.8 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.8 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.9 host 192.168.2.31 eq 389', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 389', 'permit udp host 192.168.23.1 host 192.168.2.32 eq 389', 'permit udp host 192.168.23.4 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 389', 'permit udp host 192.168.23.5 host 192.168.2.32 eq 389', 'permit udp host 192.168.23.8 host 192.168.2.32 eq 389', 'permit tcp host 192.168.23.2 host 192.168.2.28 eq 445', 'permit tcp host 192.168.23.5 host 192.168.2.28 eq 445', 'permit tcp host 192.168.23.1 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.6 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.9 host 192.168.2.31 eq 445', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.2 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.3 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.4 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.7 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.8 host 192.168.2.32 eq 445', 'permit tcp host 192.168.23.1 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.2 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.5 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.7 host 192.168.2.23 eq 8530', 'permit tcp host 192.168.23.4 host 192.168.2.31 eq 49667', 'permit tcp host 192.168.23.8 host 192.168.2.31 eq 49667', 'permit tcp host 192.168.23.1 host 192.168.2.32 eq 49670', 'permit tcp host 192.168.23.5 host 192.168.2.32 eq 49670', 'permit tcp host 192.168.23.7 host 192.168.2.32 eq 49670', 'permit tcp host 192.168.23.2 host 192.168.2.26 eq 49749', 'permit tcp host 192.168.23.5 host 192.168.2.26 eq 49749', 'permit tcp host 192.168.23.9 host 192.168.2.26 eq 49749']
You want to sort by: (port, right_ip_address, left_ip_address)

Here is a key function to sort them.

import ipaddress


def ip_sorter(text):
    parts = text.split()
    port = int(parts[-1])
    addr1 = int(ipaddress.ip_address(parts[-3]))
    addr2 = int(ipaddress.ip_address(parts[3]))
    return port, addr1, addr2
Then call:
sorted(your_set, key=ip_sorter)
For each element in your_set, the key function is called with the element as argument.
The sorter grabs port, addr1 and addr2. addr1/2 are converted to an ip_address object, then it's converted to an integer.
The port must be also an integer.

finally the sorter returns a tuple with 3 integers. The sorted function uses this information to get the items in the right order.
Thank you guys, very helpful!
DeaD_EyE, thanks for the explanation!
I try additional sorting by tcp/udp before ip1 or addr2 like this
def sort_key(item):
    rest, eq = item.split('eq')
    protocol = item.split()[1]
    _, ip1, ip2 = rest.split('host')
    ip1 = tuple(int(i) for i in ip1.split('.'))
    ip2 = tuple(int(i) for i in ip2.split('.'))
    return int(eq), ip2, protocol, ip1
or like this
def ip_sorter(text):
    parts = text.split()
    protocol = parts[1]
    port = int(parts[-1])
    addr1 = int(ipaddress.ip_address(parts[-3]))
    addr2 = int(ipaddress.ip_address(parts[3]))
    return port, addr1, protocol, addr2
but it does not work.
What is a problem?