#πŸ”’ For a list of strings, return the length which is most common.

22 messages Β· Page 1 of 1 (latest)

river wedge
#

I've got a function to split a newline separated list of strings into a list, removing any whitespace, None, or empty values.

All strings must be the same length. I check for that. I could raise an exception if they weren't, but I decided instead to return a list consisting of the strings with the most common length instead. That way if there were a few erroneous strings the function would keep chugging.

This is what I did. It works. But I'm curious if there are other betters ways of doing this.

To be clear, for a list of strings, I want a list of strings which are of the most frequent length.

Thank you.

def same_length_string_list(string_list):
    same_length = all(len(string_list[0]) == len(item) for item in string_list)
    # If the contents of the list aren't all the same length
    # Then find out the most common length, and return a list of all items with that length.
    if not same_length:
        string_lengths = {}
        for i in string_list:
            if len(i) in string_lengths: # Iterate the length key if it exists
                string_lengths[len(i)] = string_lengths[len(i)] + 1
            else: #If the length key doesn't exist already make a new one
                string_lengths[len(i)] = 1
        # Length of the most common word length. Gives the key of the highest value in a dict.
        string_length = max(string_lengths, key=string_lengths.get)
        string_list = [i for i in string_list if len(i) == string_length]
    return string_list```
proper nightBOT
#

@river wedge

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

tulip patrol
fallow dew
#

Complicated simple ops like this:

string_lengths[len(i)] = string_lengths[len(i)] + 1

can be written

string_lengths[len(i)] += 1

NB: +=, not =+

Same for a lot of other binary operators.

#

You can use a defaultdict for the dict, avoiding the "is this length new" check:

from collections import defaultdict
.......
string_lengths = defaultdict(int)

then just: string_lengths[len(i)] += 1 with no check.

river wedge
#
def equal_length_list(string_list):
    # Check if all items are equal length
    same_length = all(len(string_list[0]) == len(item) for item in string_list)
    if not same_length:
        common_length = max(Counter(len(x) for x in string_list)) #Length of most frequent item length
        string_list = [i for i in string_list if len(i) == common_length] #List of items of that length.
    return string_list```

A lot shorter and simpler. Edit: but doesn't work because max(...) returns the largest key rather than the key with the largest value.
#

hmm actually something wrong with that giv eme a seco

tulip patrol
river wedge
fleet mountain
river wedge
tulip patrol
#

!e huh? ```py
from collections import Counter
print(max(Counter(len(x) for x in ["a","a","ba","C"])))

proper nightBOT
fleet mountain
#

i think you'd want a max with a key=counter.get

counter = Counter()
max(counter, key=counter.get)
tulip patrol
#

oh yeah

#

Since I have realized I am too tired to write good code/give proper help, I'll just give the much less clean one line version then sleep ```py
max(Counter(len(x) for x in ["a","a","ba","C"]).items(), key=lambda x: x[1])[0]

fleet mountain
#

Counter(...).most_common()[0][0], though that is eagerly sorting
oh well most_common has an arg, could do Counter(...).most_common(1)[0][0] (get the list with the first most common entry, get that entry - a (len, freq) tuple, and get the length from it)

river wedge
#
def equal_length_list(string_list):
    # Check if all items are equal length
    same_length = all(len(string_list[0]) == len(x) for x in string_list)
    if not same_length:
        counter = (Counter(len(x) for x in string_list)) # Key:Value is String Length:Frequency
        common_length = max(counter, key=counter.get) # Length of most frequent item length (largest key)
        string_list = [i for i in string_list if len(i) == common_length] #List of items of that length.
    return string_list
fleet mountain
# fleet mountain not special casing the case where they are all the same length would make it eve...

another thing is this special case makes the function behaviour pretty inconsistent
if the items are of equal length, you get literally the same list back, so mutating it would mutate the one you passed as an argument
but if no - then its a new one
you could make a copy, or just not special case it. checking for same_length already requires you to go through each item, so why not just start by going through each item to do the Counter?

from collections import Counter
from collections.abc import Iterable, Sized

def eq_len[S: Sized](xs: Iterable[S]) -> list[S]:
  n = Counter(map(len, xs)).most_common(1)[0][0]
  return [x for x in xs if len(x) == n]
river wedge
#
from collections import Counter
def equal_length_list(string_list):
    # What is the most frequent string length in the list?
    most_frequent_length = Counter(len(x) for x in string_list).most_common(1)[0][0]
    return [i for i in string_list if len(i) == most_frequent_length]  # return List of items of that length.
proper nightBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.