Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Sebastiaan Stoffels
3,075 PointsOO Python - Inheritance Quiz - Combiner function - which is more pythonic?
Hi All, Just completed one of the code challenges:
Make a function called 'combiner' which takes a list as an argument. This can contain strings and ints/floats. return a string that concatenates the string items and sums the numbers. The task asked us to use 'isinstance()' to check stuff.
I was able to complete the task successfully with the code below:
def combiner(thelist):
innerlist = thelist
finalstring = ""
finalsum = 0
for item in innerlist:
if isinstance(item, str):
finalstring += item
elif isinstance(item, (int, float)):
finalsum += item
return str(finalstring) + str(finalsum)
However, as I like to do, I re-read and see how I can make it into less lines. Ultimately I removed many intermediate variables etc + used list comprehension to get it to this:
def combiner(thelist):
combinedlist = str(''.join([item for item in thelist if isinstance(item, str)])) \
+ \
str(sum([item for item in thelist if isinstance(item, (int, float))]))
return combinedlist
infact i didn't even need the 'combinedlist' variable and could have just used return for the 2 list comprehensions.
The first is easier to read ( i think ), the second is much less lines.
Which is more Pythonic? Should i be 'optimising' my code like this?
2 Answers
gyorgyandorka
13,811 PointsHi Sebastiaan!
Readability is what counts most. I think it's a good idea to replace the loop with list comprehensions, because it's denser and it can make the code more readable, but don't overdo the shortening. If a list comprehension is too complex, then it's much better to expand it to a regular for loop. Don't write any line on which you have to linger for more than a couple of seconds in order to comprehend - ideally, the reader of your code should understand it at a glance. Having said that, using comprehensions is fine, but I suggest doing it separately, and assigning them to named variables. An important part of the "clean code" paradigm is to make the code self-documenting, i.e. creating variables, methods with long, descriptive names, and use comments sparingly (only document why your code does what it does). The golden mean might be something like:
# clear and compact, with just the right amount of information to absorb on every line
def combiner(my_list):
string_items = [item for item in my_list if isinstance(item, str)]
numeric_items = [item for item in my_list if isinstance(item, (int, float))]
return ''.join(string_items) + str(sum(numeric_items))
Note: these are not objective truths by any means, just what I've learned so far. Coding style/standards are open for debate.
Also, check out the Zen of Python!
- Sidenote 1: the
innerlistvariable was unnecessary even in the first version - Sidenote 2: it's higly recommended to use underscores when a variable name is a compound word (again, for readability)
- An additional, off-topic note, this time about performance: since we're only interested in the sum of certain elements, it is a bit of an overkill to create two additional lists in memory with comprehensions - a so-called generator expression could come in handy in such situations. The syntax is the same as the list comprehension's, but we use parentheses instead of square brackets. I just mentioned it for the sake of completeness, this would matter only in case of very large data sets.
Sebastiaan Stoffels
3,075 PointsThanks for your answer Gyorgy. I do like your 'in between' version! :)
Assma Al-Adawi
8,723 PointsAssma Al-Adawi
8,723 PointsThese are some great tips! I really had a hard time with this because I did not think that the overly condensed version of the code was very readable. I also thought the innerlist part was unnecessary. Confirmed my instincts!