【问题标题】:Python Counter doesn't countPython 计数器不计算在内
【发布时间】:2015-05-14 09:20:35
【问题描述】:
import urllib2
f=urllib2.urlopen("http://www.mbnet.com.pl/dl.txt")
list = range(1,50)
counter={}

for lines in f:
    tab_lines=lines.split(" ")
    formated_tab=tab_lines[-1].strip().split(',')
    #print formated_tab
    for i in formated_tab:
        if i in list:
            counter[i]+=1
print counter.items()

我的counter 不起作用,我不知道为什么:(

这是一个彩票号码列表。我想计算每个数字抽了多少次。

【问题讨论】:

  • 不要使用列表作为变量名。

标签: python if-statement counter


【解决方案1】:

您正在比较 字符串整数。您的 if 测试永远不会匹配:

if i in list:

因为每个i 都是一个字符串。另一方面,您的 list 变量包含整数:

list = range(1,50)

i 转换为整数以测试其他整数:

if int(i) in list:

其他一些评论:

  • list 不是一个好的变量名;你正在屏蔽built-in type

  • 您可以通过对开始值和结束值使用比较运算符来测试i 是否在一个范围内:

    if 1 <= int(i) < 50:
    

    这样会更快,因为您不必每次都扫描列表。

  • 您不能假设密钥已经存在于counter 中。您必须先进行测试或使用 counter.get() 来返回默认值。例如:

    counter[i] = counter.get(i, 0) + 1
    
  • 要计算您的值,您可以使用标准库 collections.Counter() 类:

    from collections import Counter
    
    counter = Counter()
    
    for lines in f:
        tab_lines = lines.split()  # note, no argument!
        formatted_tab = map(int, tab_lines[-1].split(','))
        counter.update(i for i in formatted_tab if 0 < i < 50)
    
    print counter.most_common()
    

    在我的测试中,我没有在该文件中看到任何超出 0 到 50(不包括)范围的数字,因此您可能只需 counter.update(formatted_tab) 就可以逃脱。

【讨论】:

  • 除此之外,覆盖list不是一个好主意,counter[i]+=1会抛出一个错误,因为counter[i]还没有被设置...
【解决方案2】:

而不是使用:

counter[i] = counter.get(i, 0) + 1

你也可以试试collections.defaultdict:

counter = defaultdict(int)

所以你的最终版本应该是这样的:

import urllib2
from collections import defaultdict

f=urllib2.urlopen("http://www.mbnet.com.pl/dl.txt")
list = range(1,50)
counter=defaultdict(int)  # use defaultdict here

for lines in f:
    tab_lines=lines.split(" ")
    formated_tab=tab_lines[-1].strip().split(',')
    for i in formated_tab:
        if int(i) in list:
            counter[i] += 1  # don't worry, be happy :)
sumall=sum(counter.values())
for number, value in counter.items():
    print ('Number {} drawn {} times and it is {}% of all').format(number,value,100*value/sumall)

我会给你一个例子来展示collections.defaultdict在这里做了什么:

>>> from collections import defauldict
>>> a = {}
>>> a['notexist']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'notexist'
>>> b = defaultdict(int)
>>> b['notexist']
0

class collections.defaultdict([default_factory[, ...]]) defaultdict 是内置 dict 类的子类,所以不要害怕,但你可以用它做更多事情。一旦你指定了default_factory 变量,当key 不存在时,defaultdict 会根据default_factory 为你提供一个。请注意,只有在您使用 dict['key']dict.__getitem__(key) 时才会发生这种魔法。

doucumetaion 在这里:collections.defaultdict

【讨论】:

  • 感谢您向我展示这个功能 :) 并解释它是如何工作的 :) 我将来会使用它 :)
【解决方案3】:

除了Martin Pieters' answer,还有一个问题。您正在访问字典中不存在的字典键。而不是

counter[i]+=1

你应该使用类似的东西

counter[i] = counter.get(i, 0) + 1

【讨论】:

    【解决方案4】:

    非常感谢你们!

    我完成了这段代码:)!

    import urllib2
    f=urllib2.urlopen("http://www.mbnet.com.pl/dl.txt")
    list = range(1,50)
    counter={}
    
    for lines in f:
        tab_lines=lines.split(" ")
        formated_tab=tab_lines[-1].strip().split(',')
        for i in formated_tab:
            if int(i) in list:
                    counter[i] = counter.get(i, 0) + 1
    sumall=sum(counter.values())
    for number, value in counter.items():
        print ('Number {} drawn {} times and it is {}% of all ').format(number,value,100*value/sumall)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      相关资源
      最近更新 更多