-2

I have a list of nested key values from a large file:

mainLs = [{'99999': {'popDensity': 0.0, 'housingDensity': 1.8062141714841409e-07}, '53000': {'popDensity': None, 'housingDensity': None}, '56938': {'popDensity': None, 'housingDensity': None}, '22594': {'popDensity': 0.003762399188257728, 'housingDensity': 0.002336601878903448}, '49194': {'popDensity': 0.0, 'housingDensity': 0.0005159765063886844}, '54232': {'popDensity': 0.0, 'housingDensity': 0.00046439265846193704}, '06000': {'popDensity': None, 'housingDensity': None}, '00562': {'popDensity': 0.0007453821299310868, 'housingDensity': 0.00035915666845218}, '68084': {'popDensity': 0.0, 'housingDensity': 0.0}}]

I want to return a user-friendly string to note the place with a highest popDensity.

def find_densest(k, lst):
    placeId = max(lst, key =lambda place: lst[place][k] if place[k])
    ans =  "Densest placeFIPS is " + str(placeId) + " for " + k
    print(ans)

# Expected Output
find_densest('popDensity', mainLs)
>>> "The densest place ID is 22594 with the popDensity of 0.003762399188257728"

I need to retain multiple instances of the same place as key. Is there a way to do this?

  • do you have a list of dicts or a single dict? – Padraic Cunningham May 22 '15 at 21:57
  • I have 152 dictionary entries in a one single mainLs list. I have to use a list since the 'place' key might have repeats. – the_answer_is_xyz May 22 '15 at 22:04
  • @akh88 Then `mainLs` should start with { – JuniorCompressor May 22 '15 at 22:04
  • what output do you expect? – Padraic Cunningham May 22 '15 at 22:06
  • I think nesting it in another dictionary will be easier to loop, but then I have to worry about multiple instances of the same 'place' key (which will be overwritten in a dict) – the_answer_is_xyz May 22 '15 at 22:06
  • Please don't just say "I am getting Type Error". [edit] your question and paste the actual exception and traceback. It almost certainly explains _why_ you're getting this error—and, even if you don't understand it, the people who you're asking for help will. – abarnert May 22 '15 at 22:07
  • 1
    Also, please [edit] your question to be a [minimal, complete, verifiable example](http://stackoverflow.com/help/mcve). If someone tries to run this, they're just going to get a `SyntaxError` because your `mainLs` isn't valid; it's something halfway between a list and a dict that isn't legal as either. If you can't copy and paste this code into an interpreter and reproduce the problem, neither can the people trying to help you. – abarnert May 22 '15 at 22:09
  • okay i just edited it, thank you. i didn't expect SO to reply so fast. – the_answer_is_xyz May 22 '15 at 22:17
  • 1
    Your edited version doesn't fix either of the problems I asked above. The example input is still a `SyntaxError`, and you still don't include the exception. – abarnert May 22 '15 at 22:21

1 Answers1

1

You have two problems with your key function:

lambda density: lst[density][k]

First, the argument to the key function is going to be one element of lst—a place dict, not a density, or anything you can use as an index into list. So:

lambda place: place[k]

That's what causes your current TypeError; you're trying to use a place dict as an index into a list.


But if you fix that, you've got another problem. You're trying to call max on a set of values that includes both floats and None. That's ambiguous, and Python will not try to guess what you mean. Does None mean no population, so it should count as the minimum, or unknown population, so it should be skipped, or… what? Once you can explain the rule in English, you can translate it to Python.

For example, here's a key function that treats None as the lowest value:

place = max(lst, key=lambda place: place[k] if place[k] is not None else -1)

Or, here's a generator expression that skips over the None values:

place = max((place for place in lst if place[k] is not None),
            key=lambda place: place[k])

And meanwhile, this assumes that what you have in the first place really is a valid list of dicts. What you showed us is a SyntaxError, so it's hard to guess what you really have. Maybe a list of dicts of dicts, or maybe a dict of dicts? Without knowing that, it's definitely possible that you have another error in the way you're iterating over whatever it is that you have… but it's impossible to tell you how to fix it unless we can see what you really have.

For example, if you have a dict of dicts, each thing in mainLs is just going to be a place name, not a place dict. If, on the other hand, it's a list of dicts of dicts, then each thing in mainLs is going to be a dict whose only key is a place name and whose only value is a place dict, in which case you need to look for the density in that value, not in the top-level dict. A solution that works for one of these won't work for the others without a change.

abarnert
  • 334,953
  • 41
  • 559
  • 636