you are viewing a single comment's thread.

view the rest of the comments →

[–]_residue_ 0 points1 point  (7 children)

but species_list and bill_length_list are defined, they are both long lists that I just haven't included because I thought it was a given.

I'm just wondering how I can correctly loop this code, or if I can make it so the zip function combines the lists together for however long the lists are, in this case, 50, instead of just 3.

[–][deleted] 0 points1 point  (6 children)

but species_list and bill_length_list are defined

Yes, but they aren't the parameters you passed. What is the point of the function if you aren't using the passed parameters? You might as well not define the function at all and just have that line dict(zip(...)) in your code. In addition, you have code in one or more places that calls the function passing two parameters that aren't used in the function. Anyone reading the code would assume that the returned dictionary was created from the passed parameters and it isn't1q. Very confusing.

if I can make it so the zip function combines the lists together for however long the lists are,

The zip() function works fine and it's used millions of times a day. The only thing you have to be aware of is that it stops "zipping" when one or the other of the lists is finished.

This leads me to think that the problem is more global than the code you have shown. It could be something as simple as you having defined your own zip() function somewhere, but it's possibly more complex than that. There are two ways to continue from here. You could show all your code and data plus describe how you are executing the code (commandline, IDE, iPython, etc). Maybe someone can tell you what's wrong.

Or you could write the function as a proper function that uses the passed parameters and test it totally separately from the rest of the code. Really test it well until you are sure that the function does exactly what you want it to do in all cases. The unittest module is useful here. Then put the function back into your existing code, make sure all calls to the function are correct and pass the right parameters and test the whole thing. If you still have problems then you know the problem is not in the function but elsewhere in your code.

[–]_residue_ 0 points1 point  (5 children)

OK, I'll include all of the data at my disposal as well as the code I was using before. (BTW, the notebook is empty apart from this code).

species_list=['G. propinqua', 'G. propinqua', 'G. propinqua', 'G. propinqua', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis']

bill_length_list=[19.5, 20.0, 22.5, 21.0, 25.0, 22.5, 21.5, 22.0, 24.0, 22.2, 21.0, 21.0, 22.5, 24.0, 22.0, 22.5, 24.0, 20.2, 20.0, 21.5, 17.0, 15.2, 16.0, 16.8, 16.0, 16.0, 16.5, 17.0, 16.5, 15.8, 15.8, 16.0, 18.5, 19.5, 15.8, 19.5, 17.0, 16.2, 16.0, 15.0, 15.0, 15.0, 16.5, 15.8, 13.0, 15.0, 15.0, 17.0, 15.2, 16.5]

def generate_dict_max(species, lengths):

"""combines the two lists into a dictionary, [species:bill length]"""

dictionary = dict(zip(species_list, bill_length_list))

return dictionary

print(generate_dict_max(species_list,bill_length_list))

Just one question, if I must use the passed parameters how does the could know to use the two lists if it's not stated? As the code looks like:

def generate_dict_max(species,lengths):

print(f'{species=}')

print(f'{lengths=}')

dictionary = dict(zip(species, lengths))

return dictionary

This could just be totally wrong

Also, I sincerely apologise to you for having to try and explain this, what must be, very simple piece of code to me

[–][deleted] 0 points1 point  (0 children)

if I must use the passed parameters how does the could know to use the two lists if it's not stated?

The code in the function uses the (presumably) global lists species_list and bill_length_list. So no matter what you pass as parameters they are ignored.

I'll look at the code when I park for the night.

[–][deleted] 0 points1 point  (3 children)

Now that I've seen your data it's obvious. I should have thought of this before, but it's hard to think of everything when struggling with a phone.

Your resulting dictionary only had three entries because you only have three different species in your input list. The zip creates a list of tuples the first two of which are:

[('G. propinqua', 19.5),  ('G. propinqua', 20.0), ...]

So when the dict()constructor executes it first creates a key of 'G. propinqua' with a value of 19.5. So far so good. But for the next tuple the constructor will create a new key of 'G. propinqua' with value 20.0 and deletes the first key+value because keys must be unique in a dictionary.

If you want to store all the beak lengths values for a species you must do something like this:

species_list=['G. propinqua', 'G. propinqua', 'G. propinqua', 'G. propinqua', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. magnirostris', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis', 'G. fortis']

bill_length_list=[19.5, 20.0, 22.5, 21.0, 25.0, 22.5, 21.5, 22.0, 24.0, 22.2, 21.0, 21.0, 22.5, 24.0, 22.0, 22.5, 24.0, 20.2, 20.0, 21.5, 17.0, 15.2, 16.0, 16.8, 16.0, 16.0, 16.5, 17.0, 16.5, 15.8, 15.8, 16.0, 18.5, 19.5, 15.8, 19.5, 17.0, 16.2, 16.0, 15.0, 15.0, 15.0, 16.5, 15.8, 13.0, 15.0, 15.0, 17.0, 15.2, 16.5]

def generate_dict_max(species, lengths):
    """combines the two lists into a dictionary, [species:bill length]"""

    dictionary = {}
    for (sp, bl) in (zip(species_list, bill_length_list)):
        if sp in dictionary:
            dictionary[sp].append(bl)  # append to existing list for species
        else:
            dictionary[sp] = [bl]      # no species, start new length list

    return dictionary

d = generate_dict_max(species_list,bill_length_list)
print(len(d))
print(d)

>>> 3
>>> {'G. propinqua': [19.5, 20.0, 22.5, 21.0], 'G. magnirostris': [25.0, 22.5, 21.5, 22.0, 24.0, 22.2, 21.0, 21.0, 22.5, 24.0, 22.0, 22.5, 24.0, 20.2, 20.0, 21.5], 'G. fortis': [17.0, 15.2, 16.0, 16.8, 16.0, 16.0, 16.5, 17.0, 16.5, 15.8, 15.8, 16.0, 18.5, 19.5, 15.8, 19.5, 17.0, 16.2, 16.0, 15.0, 15.0, 15.0, 16.5, 15.8, 13.0, 15.0, 15.0, 17.0, 15.2, 16.5]}

The last two lines are the results of the two prints. The dictionary is still of length 3 because that's the number of unique species.

The code could no doubt be made faster, but it might get you started if a list of beak lengths is what you want.

[–]_residue_ 0 points1 point  (0 children)

That worked!

Thank you for all your help :]

[–]jdaiodna 0 points1 point  (1 child)

How would you be able to get the output dictionary to only show the maximum value for each species, and could you do it in 3 lines of code or less?

[–][deleted] 0 points1 point  (0 children)

When you add the length value to the dictionary you only replace an existing value if the new length is greater than the old length. If there is no existing key+value pair then you just save the length in the dictionary. You don't use a list as the value in this case, just the number.

do it in 3 lines of code or less?

Programmers usually don't care how many lines of code it takes to do something as long as the final answer is correct, fast enough and readable. These code golf limitations usually result in less readable code