简体   繁体   中英

Need to understand this python code

Having problems understanding 2 things in the code below. Problem 1: I dont understand what is themap and what is it's use. Usually when we create functions with 2 arguments like here :

def find_city(themap,state): shouldn't we enter the value of the 2 arguments themap and state when we run the program? And yet, we only give the values of state ie we enter either CA OR MI OR FL . I dont understand what is themap being used for.

Problem 2 : I dont understand the line cities['_find'] = find_city I searched google for '_find' python and the only thing I found was reference to zed shaw's book. which category does it come under or what should I read to learn more about this line?

cities = {'CA': 'San Francisco', 'MI': 'Detroit',
                     'FL': 'Jacksonville'}

cities['NY'] = 'New York'
cities['OR'] = 'Portland'

def find_city(themap, state):
    if state in themap:
        return themap[state]
    else:
        return "Not found."

# ok pay attention!
cities['_find'] = find_city

while True:
    print "State? (ENTER to quit)",
    state = raw_input("> ")

    if not state: break

    # this line is the most important ever! study!
    city_found = cities['_find'](cities, state)
    print city_found

EDIT: Could you also tell me which chapter or python topic should I study to be able to understand this better. I mean, to better understand about the questions that I asked.

this line

city_found = cities['_find'](cities, state)

is calling

def find_city(themap, state):

therefore

themap ==> cities
state ==> state

When the call is made to to find_city (note the previous assignment of cities['_find'] = find_city )

city_found = cities['_find'](cities, state)

you are sending the dictionary cities along with the state . The identifier cities gets re-mapped (renamed if you like) to themap in the function, state stays the same in this part of the code:

def find_city(themap, state)

Ie, in your "main program" the you refer to the dictionary as cities but when you make the call to the function, the function refers to it as themap . state stays the same. Names are matched by position between the identifiers in the call and those listed in the function header.

cities[_find] allows you to index into the cities dictionary using state in the find_city function.

Reading more about functions and the parameter passing mechanism, function assignments (to variables) and dictionaries in Python should help solidify your understanding of this type of code constructs. Hope this helps.

def find_city(themap,state): shouldn't we enter the value of the 2 arguments themap and state when we run the program?

No; we should pass two arguments to the function when we call the function .

Not every piece of data a program works with has to come from the user. It can supply its own data, read things from files, etc.

I dont understand the line cities['_find'] = find_city

cities is a dictionary. So cities[<anything in here>] = <anything over there> puts the <anything over there> value into the dictionary with the key <anything over here> . Here our key is the string '_find' , and the value is the function find_city . Yes, in Python, everything is an object, and that includes functions. So we can certainly store functions in a container :)

city_found = cities['_find'](cities, state)

Here, we evaluate cities['_find'] - ie, we look up the key '_find' in the dictionary cities , finding the function find_city ; then we use that result with (cities, state) . Thus it is the same as if we had written find_city(cities, state) ; that's a normal function call. state is the value that the user input, which gets passed as state ; and cities is the dictionary, which gets passed as themap . Inside the function, the named state is looked up in the cities dictionary.

city_found = cities['_find'](cities, state)  

Here you have used a calling function, and this calls the pre defined function DEF ---
it calls 'themap' for cities
and 'state' for state

But problem still remain is that why to use '_' sign before 'find'... thank you.

Themap is not map in the sense of a map of cities in a geographical sense. Python maps are a data type. It's clear the function is being passed a container with cities and that in the function it's passing a city to be looked up within the container. Maybe you're really novice-in the context of a function, a parameter takes on a different name, but has the same value at the top of the function.

In python everything has a value that can be assigned, even functions. The problem 2 you're asking about is just a new name for the same function.

  1. Yes you are right - find_city accepts two arguments, and that how many it's given when it's called, namely

    cities['_find'](cities, state)

  2. This just means that an entry is added to the cities map. The key for the entry is the string "_find" and the value is the finction find_city. That's why the expression cities['_find'] returns the function and then you call it with two arguments.

Well, themap is a so called map or dictionary or hash-based container . It is used just like an array because the operator[] is overloaded somehow (I come from C++ background, and it is doable in C++). When you assign 'New York' to cities['NY'] the key 'NY' is created automatically and the value corresponding to that key is 'New York'.

To answer your second question, find_city is a function pointer of some sort which is paired with the key '_find' . Here _find is an arbitrary choice of key. You could have used find or Find or anything else you wanted. No wonder you did not find anything about it on Google. The line cities['_find'](cities, state) actually internally gets translated to find_city(cities, state) .

Hope I have helped a bit, :).

Functions are values you can pass around.

Saying cities['_find'] is equivalent to saying find_city , since they both evaluate to that function. fn = cities['_find'] fn(cities, state)

In python, function call syntax applied to a value tries to call that value with the arguments, if it is callable. So in your case, cities['_find'].__call__(cities, state) ends up being executed.

You just look at two lines from your code:

  1. cities['_find'] = find_city

  2. city_found = cities['find'](cities, state)

Explanation for (1):

As cities is dictionary before you use cities['_find'] . print it...

print(cities)
Output: {'CA': 'San Francisco', 'MI': 'Detroit', 'FL': 'Jacksonville', 'NY': 'New York', 'OR': 'Portland'} 

Now after using cities['_find']=find_city ,

print(cities)  
Output: {'CA': 'San Francisco', 'MI': 'Detroit', 'FL': 'Jacksonville', 'NY': 'New York', 'OR': 'Portland', *'_find': <function find_city at 0x01BAB738*>}

Here the last dictionary item is added with key _find and the value is the function find_city .

Explanation for (2):

Now city_found = cities['find'](cities, state)

Now we know that find_city is in the dict at _find , that means we can do work with it. The it can be broken down like this:

  1. Python sees city_found = and knows we want to make a new variable.

  2. It then reads cities and finds that variable, it's a dict.

  3. Then there's ['_find'] which will index into the cities dict and pull out whatever is at _find .

  4. What is at ['_find'] is our function find_city so Python then knows it's got a function, and it does the function call.

  5. The parameters cities, state are passed to this function find_city , and it runs because it's called.

  6. find_city then tries to look up states inside cities, and returns what it finds.

  7. Python takes what find_city returned, and finally that is what is assigned to city_found .

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