简体   繁体   English

如何根据 output 的长度对这个进行排序?

[英]How can I sort this according to the length of the output?

So I wrote this code with the help of Stack Overflow users, and here it is...所以我在 Stack Overflow 用户的帮助下编写了这段代码,这里是......

def letter_total(filename: str):
    chars = list(filename)
    chars_unique = set(chars)
    chars_unique.remove(' ')
    result = []
    for x in chars_unique:
        result.append([x, chars.count(x)*('*')])
    return result
def letter_count(filename: str):
    l_count = letter_total(filename)
    for c in sorted(l_count):
        print(c[0], c[1])
print(letter_count(filename='How was your day'))

and this is the resulting output...这是生成的 output...

H *
a **
d *
o **
r *
s *
u *
w **
y **
None

but I want my output to be printed in order from most numbers of * to the least number of them.但我希望我的 output 以从*数量最多到数量最少的顺序打印。 (if there are same number of '*' in two different letters, then I want it to return the two letters in alphabetical order) (如果两个不同的字母中有相同数量的“*”,那么我希望它按字母顺序返回这两个字母)

somy output should look like this somy output 应该是这样的

a **
o **
w **
y **
d *
H *
r *
s *

How can I accomplish this without using key = lamda and only using sorted() ??如何在不使用 key = lamda 且仅使用 sorted() 的情况下完成此操作?

You're asking to drive in a screw without using a screwdriver and only using your bare fingers , but okay.您要求在不使用螺丝刀且仅使用裸手指的情况下拧螺丝,但没关系。

If you store each tally as a list [negative_count, letter] instead of [letter, stars] , the default ordering will first sort by negative_count (longer first) and use letter as a tie-breaker, exactly as you intended.如果您将每个计数存储为列表[negative_count, letter]而不是[letter, stars] ,则默认排序将首先按negative_count (较长的优先)排序,并使用letter作为决胜局,完全符合您的预期。 Note that capitals sort before lowercase letters.请注意,大写字母排在小写字母之前。

With minimal changes to your code:对您的代码进行最少的更改:

def letter_total(filename: str):
    chars = list(filename)
    chars_unique = set(chars)
    chars_unique.remove(' ')
    result = []
    for x in chars_unique:
        result.append([-chars.count(x), x])
    return result
def letter_count(filename: str):
    l_count = letter_total(filename)
    for c in sorted(l_count):
        print(c[1], (-c[0]) * '*')
print(letter_count(filename='How was your day'))

Then a couple more pointers:然后还有几个指针:

  • letter_count is already doing the printing; letter_count已经在打印了; no need to also print its return value (which is None ).无需同时打印其返回值(即None )。
  • It's more efficient and idiomatic to use tuples (stars, letter) instead of lists here.在这里使用元组(stars, letter)而不是列表更有效和更惯用。
  • This code is O(n²) which means it's rather inefficient.此代码为 O(n²),这意味着它的效率相当低。 For each unique letter, it's running through the entire string to count just that letter.对于每个唯一的字母,它会遍历整个字符串以仅计算该字母。 It's more efficient to run through the string once, and keep a tally in a dict .遍历字符串一次,并在dict中保留一个计数更有效。 Then as the last step, convert the dict into a list of tuples.然后作为最后一步,将dict转换为元组列表。

Putting all that together:把所有这些放在一起:

def letter_total(filename: str):
    l_count = {}
    for x in filename:
        if x != ' ':
            if x not in l_count:
                l_count[x] = 0
            l_count[x] -= 1
    result = [(count, letter) for letter, count in l_count.items()]
    return result
def letter_count(filename: str):
    l_count = letter_total(filename)
    for c in sorted(l_count):
        print(c[1], (-c[0]) * '*')
print(letter_count(filename='How was your day'))

I understand you're just learning, but in production code, I would recommend collections.Counter which does exactly this job for you:我知道您只是在学习,但在生产代码中,我会推荐collections.Counter ,它可以为您完成这项工作:

>>> from collections import Counter
>>> list(Counter('How was your day').items())
[(' ', 3), ('H', 1), ('a', 2), ('d', 1), ('o', 2), ('r', 1), ('s', 1), ('u', 1), ('w', 2), ('y', 2)]

clean the input string清理输入字符串

then use Counter with its method most_common to get a list of letters counted by their occurence然后使用 Counter 及其方法 most_common 来获取按出现次数计数的字母列表

then group the output list of tuples l by second element然后按第二个元素对元组 l 的 output 列表进行分组

apply sorted应用排序

from collections import Counter
from typing import List, Tuple

s: str = 'How was your day'.replace(" ", "")

ll: List[Tuple[str, int]] = Counter(s).most_common()

res = sum([sorted(v, key=lambda ch: ch[0].lower()) for k,v in groupby(ll), lambda x: x[1])], [])

res = [(x, y * "*") for x,y in res]

OUTPUT: OUTPUT:

 [('a', '**'),
 ('o', '**'),
 ('w', '**'),
 ('y', '**'),
 ('d', '*'),
 ('H', '*'),
 ('r', '*'),
 ('s', '*'),
 ('u', '*')]

This way: sorted(sorted(l_count), key = lambda i:-i[1])这样: sorted(sorted(l_count), key = lambda i:-i[1])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM