Ujjwal Singh Baghel
Ujjwal Singh Baghel

Reputation: 393

How to pass an object with attribute Value in python function

I was working on the sorting but I'm not able to call the function with the specific way.

Basically, what I want to do is to create a function that takes a list of object Node with attribute Value and returns a list with the items from the original list stored into sublists. Items of the same value should be in the same sublist and sorted in descending order.

For continuing the code I want to know what should be the parameter of this.

def advanced_sort(<What will come here according to the call>):

Function call:

advanced_sort([Node(1), Node(2), Node(1),Node(2)])

Can anyone please help me out with the code? Thanks in advance.

Upvotes: 0

Views: 436

Answers (3)

chepner
chepner

Reputation: 530960

advanced_sort takes a single argument: a list (or possibly an arbitrary iterable). As such, the signature only has one argument:

def advanced_sort(nodes):

Ignoring type hints, the signature does not and cannot reflect the internal structure of the single argument; it's just a name to refer to the passed value inside the body of the function.

Inside the body, you can write code that assumes that nodes is a list, and that further each element of the list is a Node instance, so that you can do things like assume each value as a Value attribute.

def advanced_sort(nodes):
    # If nodes is iterable, then x refers to a different
    # element of the iterable each time through the loop.
    for x in nodes:
        # If nodes is a list of Node instances, then
        # x is a Node instance, and thus you can access
        # its Value attribute in the normal fashion.
        print("Found value {}".format(x.Value))

Assuming a definition of Node like

class Node:
    def __init__(self, v):
        self.Value = v

the above definition of advanced_sort will produce the following output:

>>> advanced_sort([Node(3), Node(2), Node(1),Node(2)])
Found value 1
Found value 2
Found value 3
Found value 4

Upvotes: 1

R_B
R_B

Reputation: 59

The argument is a single iterable object such as a list, a tuple, a set, ...

Then you iterate on the items as in chepner's response.

For exemple you can use a dictionary to group the Nodes by value:

def advanced_sort(node_list): 
    ret = dict() 
    for node in node_list: 
        if node.value not in ret.keys(): 
            ret[node.value] = list() 
        ret[node.value].append(node)

     return [ret[value] for value in sorted(ret.keys(), reverse=True)] #descending order
advanced_sort([Node(3), Node(2), Node(1),Node(1)])
>>> [[Node(3)], [Node(2)], [Node(1),Node(1)]] 

Upvotes: 1

Paul M.
Paul M.

Reputation: 10799

Are you able to make changes to the Node class? In that case, you could do something like this:

from functools import total_ordering


@total_ordering
class Node:

    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        if not isinstance(other, Node):
            return NotImplemented
        return self.value == other.value

    def __lt__(self, other):
        if not isinstance(other, Node):
            return NotImplemented
        return self.value < other.value

    def __str__(self):
        return f"({self.value})"


def main():

    from itertools import groupby


    nodes = [Node(1), Node(2), Node(1), Node(2)]
    nodes_sorted = sorted(nodes, reverse=True)
    nodes_sublists = [list(group) for key, group in groupby(nodes_sorted)]

    for sublist in nodes_sublists:
        print(*map(str, sublist))

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

Output:

(2) (2)
(1) (1)

Upvotes: 0

Related Questions