简体   繁体   中英

Not Understanding Passing Tuple As Argument

I am really having a hard time wrapping my head around this one. I think I must be missing on several concepts, because it works, I am just confused how.

I understand that I am creating a class with an initializer and two methods. In the initializer, I am setting two instance attributes (_queue and _index). The leading underscore indicates they are implementation details.

I can see that the 'push' method defined takes three arguments. The first is the object on which the method is called (aka the instance). The second are two variables.

I see that heapq.heappush() is taking two arguments: Arg1 - self._queue - basically the list created in the initializer Arg2 - A tuple

Arg2 is what gets me. How can we accept a tuple with 3 elements? I see nothing in the heapq.heappush() documentation that says we are able to do this. It just says you put in what you want to append to, and then what you are appending. And I don't see something at further parses the tuple to make it into the one argument that I think it should be taking. When I just try passing a tuple like that into heapq.heappush() in a normal python window it fails.

Can someone help a novice like me understand whatever concept I seem to be missing?

Thanks so much!

import  heapq
class PriorityQueue :
    def  __init__ (self):
        self._queue  =  [] 
        self._index  =  0 
    def push(self, item, priority):
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index  +=  1 #add one to the index
    def pop( self ):
        return heapq.heappop(self._queue )[- 1 ]


class Item:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Item({!r})'.format(self.name)

Lets step back and think about what happens when python compiles your program. When python sees

(-priority, self._index, item)

It compiles that into byte code that looks up those three pieces of data and creates a single tuple to hold them. To see, you could add a line print(type((-priority, self._index, item))) to show its a single object.

Now on to the full statement

heapq.heappush(self._queue, (-priority, self._index, item))

after python creates that tuple, it uses it as the second item in the method call. So by the time heappush sees it, it is a single item as required. Generally, python can evaluate any expression inside the function's call and use the constructed object as the parameter. Its exactly equivalent to the following code except it doesn't have to go through an intermediate variable

_stuff = (-priority, self._index, item)
heapq.heappush(self._queue, _stuff)
del _stuff

It can be confusing because parens are used to make tuples and to define functions. The difference is they are used in different places (that's one of the reasons you need the def keyword) so python knows what to do in each case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM