16

I'm new to programming and currently taking a CSC 110 class. Our assignment is to create a bunch functions that do all sorts of things with some data that is given. I have taken all that data and put it into a dictionary but I'm having some trouble getting the data I want out of it.

Here is my problem:

I have a dictionary that stores a bunch of countries followed by a list that includes their population and GDP. Formatted something like this

{'country': [population, GDP], ...}

My task is to loop through this and find the country with the highest population or GDP then print:

'The country with the highest population is ' + highCountry+\
    ' with a population of ' + format(highPop, ',.0f')+'.')

In order to do this I wrote this function (this one is specifically for highest population but they all look about the same).

def highestPop(worldInfo):
        highPop = worldInfo[next(iter(worldInfo))][0] #Grabs first countries Population
        highCountry = next(iter(worldInfo))#Grabs first country in worldInfo

        for k,v in worldInfo.items():
                if v[0] > highPop:
                    highPop = v[0]
                    highCountry = k

        return highPop,highCountry

While this is working for me I gotta think there is an easier way to do this. Also I'm not 100% sure how [next(iter(worldInfo))] works. Does this just grab the first value it sees?

Thanks for your help in advance!

Edit: Sorry I guess I wasn't clear. I need to pass the countries population but also the countries name. So I can print both of them in my main function.

Eb946207
  • 748
  • 8
  • 26
Luke Kelly
  • 423
  • 4
  • 14
  • 4
    There is the function `max()` which can take something iterable (like the dict items). If you give a `key` function as parameter which extracts the desired value (here: population) it will return the item you want. – Michael Butscher Dec 04 '18 at 02:09
  • 1
    Possible duplicate of [Getting key with maximum value in dictionary?](https://stackoverflow.com/questions/268272/getting-key-with-maximum-value-in-dictionary) – Azat Ibrakov Dec 04 '18 at 09:46

3 Answers3

22

I think you're looking for this:

max(worldInfo.items(), key=lambda x: x[1][0])

This will return both the country name and its info. For instance:

('france', [100, 22])

The max() function can work on python "iterables" which is a fancy word for anything that can be cycled or looped through. Thus it cycles or loops through the thing you put into it and spits out the item that's the highest.

But how does it judge which tuple is highest? Which is higher: France or Germany? You have to specify a key (some specification for how to judge each item). The key=lambda etc specifies a function that given an item (x), judge that item based on x[1][0]. In this instance if the item is ('france', [100, 22]) then x[1][0] is 100. So the x[1][0] of each item is compared and the item with the highest one is returned.

The next() and iter() functions are for python iterators. For example:

mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)

print(next(myit)) #=> apple
print(next(myit)) #=> banana
print(next(myit)) #=> cherry
Conner
  • 30,144
  • 8
  • 52
  • 73
  • 1
    Yes this is exactly what i was looking for. Now I just need to spend 30 minutes figuring out what all that means. – Luke Kelly Dec 04 '18 at 02:36
  • 1
    @Conner Your comment would be far more useful if edited into your answer, just sayin'. – Ian Kemp Dec 04 '18 at 08:41
  • 1
    Is it just because I'm old, crotchety and learned to program in BASIC and FORTRAN IV, that I think that using Python's max() function -- heck, using anything but arrays and comparison operators -- is **cheating of the highest order**? – RonJohn Dec 04 '18 at 09:48
  • 4
    @RonJohn I'm old and cranky, but I'm also too lazy to rewrite something that already exists. – JollyJoker Dec 04 '18 at 11:49
  • 2
    @JollyJoker you're a **student** ("new to programming and currently taking a CSC 110 class"), and thus **need** to write for yourself -- at least once -- your own min(), max(), bubble sort, quicksort, linked list, binary tree, hashing, etc implementations. – RonJohn Dec 04 '18 at 14:03
9

Use the max() function, like so:

max(item[0] for item in county_dict.values()) #use item[1] for GDP!

Also try storing the values not in a list ([a, b]) but in a tuple ((a, b)).

Edit: Like iamanigeeit said in the comments, this works to give you the country name as well:

max(data[0], country for country, data in country_dict.items())
Eb946207
  • 748
  • 8
  • 26
  • So i have to pass back not just the countries population but also the countries name as well. Is there a way to get that info from what is given above? – Luke Kelly Dec 04 '18 at 02:11
  • @LukeKelly Well, you could get the name from the value returned by `max()` if the values are always different. A loop would also work but I would not recommend it. – Eb946207 Dec 04 '18 at 02:15
  • 1
    `max(data[0], country for country, data in country_dict.items())` – iamanigeeit Dec 04 '18 at 02:36
  • @iamanigeeit That works, nice! I would just swap the values of the first part to read: `country, data[0]` Other than that, awesome! – Eb946207 Dec 04 '18 at 02:39
  • but tuples are compared from first element... that's why i put `data[0]` first – iamanigeeit Dec 04 '18 at 02:40
6

An efficient solution to get the key with the highest value: you can use the max function this way:

highCountry = max(worldInfo, key=lambda k: worldInfo[k][0])

The key argument is a function that specifies what values you want to use to determine the max.max(data[0], country for country, data in country_dict.items())

And obviously :

highPop = worldInfo[highCountry][0]
Axel Puig
  • 1,304
  • 9
  • 19
  • 1
    Correction - I used a generator comprension, which generates the values _lazily_, so it is not slow (or less efficient). However, great idea using `max()` with `key` for sorting! – Eb946207 Dec 04 '18 at 02:29
  • I'm using both of the provided comments to fix this . `highCountry = max(worldInfo, key=lambda k: worldInfo[k][0])` `highPop = max(item[0] for item in worldInfo.values()) #use item[1] for GDP!` Is there any reason I shouldn't' do this? – Luke Kelly Dec 04 '18 at 02:31
  • Indeed @EthanK, however you can't get the key efficiently. :) – Axel Puig Dec 04 '18 at 02:37
  • @LukeKelly once you have the key, you can directly access the corresponding value, it is more efficient. See my edited answer. – Axel Puig Dec 04 '18 at 02:37
  • unless it's Python 2, then we'd need `.itervalues()` and `.iteritems()` – iamanigeeit Dec 04 '18 at 02:38