python元组的创建 取值 排序 计数_在Python中对计数列表进行排序

(我对任何一种编程都是全新的,因此在回答时请尽可能具体)

问题:我编写了一个程序来解决pythonchallenge.com 2级问题。该程序可以运行,但是结果混乱。 我想将字符计数的结果排序到一个漂亮的列表中。 当我尝试使用sorted()对字符计数的结果进行排序时,它会删除所有计数,并仅列出字符串中的字符。 我需要能够查看文件中每个字符的数量。 无论如何,这里是代码:

countstring = open('pagesource.txt').read()

charcount = {}

for x in countstring:

charcount[x] = charcount.get(x, 0) + 1

print charcount

这就是我在cmd中得到的:

>>> {'

': 1219, '!': 6079, '#': 6115, '%': 6104, '$': 6046, '&': 6043, ')': 6186, '

(': 6154, '+': 6066, '*': 6034, '@': 6157, '[': 6108, ']': 6152, '_': 6112, '^':

6030, 'a': 1, 'e': 1, 'i': 1, 'l': 1, 'q': 1, 'u': 1, 't': 1, 'y': 1, '{': 6046

, '}': 6105}

如果我向其中添加诸如print sorted(charcount)之类的sorted()函数,则会在cmd中获得此信息:

>>> ['

', '!', '#', '$', '%', '&', '(', ')', '*', '+', '@', '[', ']', '^', '_', 'a'

, 'e', 'i', 'l', 'q', 't', 'u', 'y', '{', '}']

感谢您的解决方案,如果您能抽出宝贵的时间向代码中添加注释,以解释一切,我将不胜感激!

您应该真正使用Counter类,而不是重新发明自己的轮子。

charcount是一个字典,并且字典没有隐式的排序顺序。因此,我们必须将其转换为可以排序的列表。该列表中的每个条目将是一个由计数和字符组成的元组。

charcount.items()已经给我们一个类似于[('

', 1219), ('!', 6079)]的列表。不幸的是,如果我们对该列表进行排序,它将首先按字符排序,然后(如果字符相等)按计数排序,而不是相反。因此,我们需要一个键函数来告诉排序先查看计数,然后再查看(如果计数相等)字符。幸运的是,我们的关键功能非常简单。它只是在元组周围交换:

lambda (char,count): (count, char)

或者,我们可以使用列表推导来交换值,得到类似:[('

', 1219), ('!', 6079)],然后进行排序,然后再次交换值。

charcount_list = sorted(charcount.items(), key=lambda (char,count):(count, char))

charcount_list现在将是:

[('a', 1), ('e', 1), ('i', 1), ('l', 1), ('q', 1), ('t', 1), ('u', 1), ('y', 1),

('

', 1219), ('^', 6030), ('*', 6034), ('&', 6043), ('$', 6046), ('{', 6046),

('+', 6066), ('!', 6079), ('%', 6104), ('}', 6105), ('[', 6108), ('_', 6112),

('#', 6115), (']', 6152), (' (', 6154), ('@', 6157), (')', 6186)]

如果需要相反的顺序,只需指定要排序的reverse=True参数即可。

在2.7之前的版本中至少为defaultdict。

这是一个丑陋的键函数-使用您最初在此处具有的列表理解,或者如果您真的想同时按值和键进行排序,请使用itemgetter(1, 0)。

@agf为什么那个lambda丑陋?每个Python程序员都会立即了解这里发生的事情。我同意使用itemgetter会使它更短一些(如果您不算导入的话),但不一定更具可读性。

与sorted((v, k) for k, v in charcount.iteritems())或itemgetter版本相比,它对我来说看起来很丑。

>>> from operator import itemgetter

>>> sorted(charcount.items(), key=itemgetter(1))

[('a', 1), ('e', 1), ('i', 1), ('l', 1), ('q', 1), ('u', 1), ('t', 1), ('y', 1), ('

', 1219), ('^', 6030), ('*', 6034), ('&', 6043), ('$', 6046), ('{', 6046), ('+', 6066), ('!', 6079), ('%', 6104), ('}', 6105), ('[', 6108), ('_', 6112), ('#', 6115), (']', 6152), (' (', 6154), ('@', 6157), (')', 6186)]

尽管这很简洁,但问题提出了:"我需要保持查看文件中每个字符的数量的能力"。

@phihag,是的,我看到并修复了它

字典({}的含义)是无序集合。这意味着您无法以任何有意义的方式对它们进行排序。我建议将信息存储为元组[(),...]的列表,然后根据该列表对其进行排序。

foo = [('a', 123), ('b', 345)]

def key_function(x):

return x[1]

sorted_list = sorted(foo, key_function)

print sorted_list

如您所见,sorted带有可选的第二个参数。该参数的目的是提供一个告诉已排序的事物如何排序的函数。您要做的就是分解列表中每个元组的信息以提供可以排序的值,因为您不能真正以任何有意义的方式对元组列表进行排序。

说得通?

也可以这样写:print sorted(foo, key=lambda (x,y): y)

lambda只是意味着没有名称的内联函数,它允许您以其他方式分解元组。

您可以通过执行print [y for (x,y) in sorted_list]来了解其工作原理

您甚至可以像这样重新定义键功能:

def key_function(x):

x,y = x

return y

顺便说一句,为了清楚起见,我只在括号中加了一个。如果您未定义函数,则逗号为元组构造函数。

您应该真正将其称为key_function,因为它没有排序,只是返回了键。

字典是通过键进行迭代的,因此,当您将字典传递给sorted时,会得到键的排序列表。按值对字典的项目元组进行排序,以获取已排序元组的列表。

sorted_charcount = sorted(charcount.items(), key=lambda item: item[1])

如果您使用的是Python 2.7+,则可以使用元组列表来初始化OrderedDict,这将保持项目元组的排序顺序。

他说:"我想将字符计数的结果整理到一个漂亮的列表中。"同样,"您不能对字典进行排序"是错误的,您可以对字典进行排序(正如您和其他答案所显示的那样),而字典只是没有排序。

固定我的答案

已有其他答案给出了这种确切的解决方案。

当我开始写答案时,该问题尚未得到解答。删除或保留答案没有多大意义,所以我保留了它。

charcount是dict(词典)。迭代字典会迭代其键,这就是sorted()导致键排序列表的原因。

您需要获取项目列表,然后按第二个值对其进行排序:

sorted(charcount.items(), key=lambda t: t[1])

sorted(charcount.items(), key=lambda item: item[1])

您将不得不使用charcount.items()而不是charcount

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值