DEV Community

Discussion on: Solving a Job Application Code Challenge

Collapse
 
darkdoc profile image
darkdoc

Hey!
Can someone check my python solution? Any hints where/how can the code be better?

repl.it/Mnem/0

TY

Collapse
 
rpalo profile image
Ryan Palo • Edited

Hi! A couple of notes that you can take or leave.

You don't necessarily have to loop through and initialize each key for strngs manually. Here's a couple of alternatives.

# Your version
strngs = {}
for char in initchar:
    strngs[char] = 0

# you can create a dict out of a sequence of keys and starting value
# credit: @edh_developer
strngs = dict.fromkeys(initchar, 0)

# you can also use a defaultdict, which creates the key with a default value
# if it doesn't find the key there on access
from collections import defaultdict
strngs = defaultdict(int) # defaults to zero

You can use shorthand notation if you're modifying a value inplace.

# Your version
strngs[char] = strngs[char] + 1

# shortcut
strngs[char] += 1

You can use dict.items to get a list of pairs out of a dict that is much easier to sort. Then you don't have to manually sort and delete items out of your dict.

# Your version
while (strngs != {}):
    maximum = max(strngs, key=strngs.get)
    word = word + maximum
    del strngs[maximum]

# Could be
pairs = strngs.items()
desc = sorted(pairs, key=lambda x: x[1]) # the key= argument lets us
                                        # sort by the second item
desc_letters = ''.join(x[0] for x in desc) # Grab the first value (letter) from each pair

Some things to look up here for more information:

In general, when you're building a string, it's usually more performant, easier, and less error prone to build the whole thing as a list and join it at the end.

# Instead of this:
word = ""
for item in things:
    word = word + complicated_process(item)

# Since strings are immutable, this forces you to throw away
# your old string and create a new one *each time* which is expensive

# More efficient:
word  = []
for item in things:
    word.append(complicated_process(item))

letters = ''.join(word)

# Use list comprehensions (see link below) for even faster,
# cleaner, more pythonic code :)

word = [complicated_process(item) for item in things]
letters = ''.join(word)

# Use a generator expression (like above) for *even better* results!
letters = ''.join(complicated_process(item) for item in things)

Here's a link on list comprehensions

Hopefully this helps. I'm not sure how comfortable you are with Python, so I tried to cover everything. Let me know if you have any questions 😁

Collapse
 
dimven profile image
Dimitar Venkov • Edited

Here's a py3 version using the builtin dict and iterators:

from operator import itemgetter
long_string = "..."

counter = dict()
for c in iter(long_string):
counter[c] = counter.get(c, 0) + 1

sorted_chars = [k for (k, v) in sorted(counter.items(), key=itemgetter(1), reverse=True)]
word = "".join(sorted_chars[:sorted_chars.index('_')] )

print(word)