2012-10-02 67 views
0
return function.count('1') + given.count('2') + given.count('3') 

有沒有什麼辦法可以簡化這條線? 還我試過 回報function.count(「1」,「2」,「3」),但運行的錯誤 的目標是計算字符串中包含的笑所有數字在Python中結合多個計數項?

+3

是'function'不同於'given'? – unutbu

+0

請澄清這個問題,更仔細地定義你的輸入和你想要的輸出。謝謝! – Michael

回答

3

假設function是一樣的作爲given

sum(function.count(x) for x in '1 2 3'.split()) 

變量名稱function(和given)是有點混亂,因爲這個問題也說

目標是統計字符串中包含的所有數字。

所以,如果function是一個字符串,你希望計數擴展到所有的數字,你可以使用

import string 
sum(function.count(x) for x in string.digits) 

這足以如果function是一個簡短的字符串。但請注意,每次撥打count都需要全部通過字符串function。如果function是一個非常大的字符串,則執行10次傳遞可能是低效的。

在這種情況下,它可能是更好丟棄不是數字在一個通字符:

def onepass(x): 
    return sum(1 for c in x if c in string.digits) 

或者,你可以從字符串中刪除所有的非數字字符(使用translate method)然後使用len。例如:

def drop_nondigits(x): 
    # The essential idea comes from the translator recipe in Python Cookbook; 
    # It can also be found here 
    # http://code.activestate.com/recipes/303342-simple-wrapper-for-stringtranslate/ 
    keep = string.digits 
    allchars = string.maketrans('', '') 
    delete = allchars.translate(allchars, keep) 
    return len(x.translate(allchars, delete))  

而且出於好奇,讓我們把它比作使用collections.Counter

import collections 
def using_counter(x): 
    counter = collections.Counter(x) 
    return sum(counter[d] for d in string.digits) 

事實證明,drop_nondigits最快

In [26]: x = 'some very large string 123456' * 1000 

In [38]: %timeit using_counter(x) 
100 loops, best of 3: 7.26 ms per loop 

In [29]: %timeit onepass(x) 
100 loops, best of 3: 2.52 ms per loop 

In [32]: %timeit drop_nondigits(x) 
10000 loops, best of 3: 34.9 us per loop 
+0

這將在''1 2 3'.split()'中每個'x'需要一次線性傳遞。一個更好的解決方案會做一個線性傳遞。所以使用'計數器'可能是一個更好的主意 – inspectorG4dget

+0

分割字符串''1 2 3''是微不足道的。你可以簡單地使用'['1','2','3']',我只是認爲''1 2 3'.split()'更好。使用'Counter'的問題是你可能會計算許多你不感興趣的東西。 – unutbu

+0

效率瓶頸來自n個線性通道,其中n = len(「1 2 3」.split())' 。使用'集合。計數器'在計算我們不關心的東西時浪費了一些空間,但它只是一個線性傳遞。 – inspectorG4dget

2

使用Counter()來算包含在字符串中的所有數字:

>>> from collections import Counter 
>>> count= Counter("abcd12341134..09--01abc") 
>>> [x for x in count.items() if x[0] in ""] 
[('1', 4), ('0', 2), ('3', 2), ('2', 1), ('4', 2), ('9', 1)] 

或使用Counter()filter()

>>> strs="abcd12341134..09--01abc" 
>>> Counter(filter(lambda x:x in "",strs)) 
Counter({'1': 4, '0': 2, '3': 2, '4': 2, '2': 1, '9': 1})