计算字符串中字符出现次数的最佳方法

发布于 2024-12-28 13:45:25 字数 300 浏览 7 评论 0原文

您好,我正在尝试将这些 python 行写在一行中,但由于代码正在执行的字典修改而出现一些错误。

for i in range(len(string)):
    if string[i] in dict:
        dict[string[i]] += 1

我相信的一般语法是

abc = [i for i in len(x) if x[i] in array]

有人可以告诉我这如何工作考虑到我将 1 添加到字典中的值

谢谢

Hello I am trying to write these python lines in a single line but getting some errors due to the dictionary modifications the code is doing.

for i in range(len(string)):
    if string[i] in dict:
        dict[string[i]] += 1

the general syntax I believe is

abc = [i for i in len(x) if x[i] in array]

Would it be possible for someone to tell me how this might work considering that I am adding 1 to the value in a dictionary

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深白境迁sunset 2025-01-04 13:45:25

您想要做的事情可以使用 dict生成器表达式str.count()

abc = dict((c, string.count(c)) for c in string)

替代使用set(string) (摘自下面 soulcheck 的评论)

abc = dict((c, string.count(c)) for c in set(string))

时机

看到下面的评论,我在这个答案和其他答案中进行了一些测试。 (使用 python-3.2)

测试功能:

@time_me
def test_dict(string, iterations):
    """dict((c, string.count(c)) for c in string)"""
    for i in range(iterations):
        dict((c, string.count(c)) for c in string)

@time_me
def test_set(string, iterations):
    """dict((c, string.count(c)) for c in set(string))"""
    for i in range(iterations):
        dict((c, string.count(c)) for c in set(string))

@time_me
def test_counter(string, iterations):
    """Counter(string)"""
    for i in range(iterations):
        Counter(string)

@time_me
def test_for(string, iterations, d):
    """for loop from cha0site"""
    for i in range(iterations):
        for c in string:
            if c in d:
                d[c] += 1

@time_me
def test_default_dict(string, iterations):
    """defaultdict from joaquin"""
    for i in range(iterations):
        mydict = defaultdict(int)
        for mychar in string:
            mydict[mychar] += 1

测试执行:

d_ini = dict((c, 0) for c in string.ascii_letters)
words = ['hand', 'marvelous', 'supercalifragilisticexpialidocious']

for word in words:
    print('-- {} --'.format(word))
    test_dict(word, 100000)
    test_set(word, 100000)
    test_counter(word, 100000)
    test_for(word, 100000, d_ini)
    test_default_dict(word, 100000)
    print()

print('-- {} --'.format('Pride and Prejudcie - Chapter 3 '))

test_dict(ch, 1000)
test_set(ch, 1000)
test_counter(ch, 1000)
test_for(ch, 1000, d_ini)
test_default_dict(ch, 1000)

测试结果:

-- hand --
389.091 ms -  dict((c, string.count(c)) for c in string)
438.000 ms -  dict((c, string.count(c)) for c in set(string))
867.069 ms -  Counter(string)
100.204 ms -  for loop from cha0site
241.070 ms -  defaultdict from joaquin

-- marvelous --
654.826 ms -  dict((c, string.count(c)) for c in string)
729.153 ms -  dict((c, string.count(c)) for c in set(string))
1253.767 ms -  Counter(string)
201.406 ms -  for loop from cha0site
460.014 ms -  defaultdict from joaquin

-- supercalifragilisticexpialidocious --
1900.594 ms -  dict((c, string.count(c)) for c in string)
1104.942 ms -  dict((c, string.count(c)) for c in set(string))
2513.745 ms -  Counter(string)
703.506 ms -  for loop from cha0site
935.503 ms -  defaultdict from joaquin

# !!!: Do not compare this last result with the others because is timed
#      with 1000 iterations instead of 100000
-- Pride and Prejudcie - Chapter 3  --
155315.108 ms -  dict((c, string.count(c)) for c in string)
982.582 ms -  dict((c, string.count(c)) for c in set(string))
4371.579 ms -  Counter(string)
1609.623 ms -  for loop from cha0site
1300.643 ms -  defaultdict from joaquin

What you're trying to do can be done with dict, a generator expression and str.count():

abc = dict((c, string.count(c)) for c in string)

Alternative using set(string) (from a comment down below by soulcheck):

abc = dict((c, string.count(c)) for c in set(string))

Timing

Seen the comments down below I performed a little testing among this and other answers. (with python-3.2)

Test functions:

@time_me
def test_dict(string, iterations):
    """dict((c, string.count(c)) for c in string)"""
    for i in range(iterations):
        dict((c, string.count(c)) for c in string)

@time_me
def test_set(string, iterations):
    """dict((c, string.count(c)) for c in set(string))"""
    for i in range(iterations):
        dict((c, string.count(c)) for c in set(string))

@time_me
def test_counter(string, iterations):
    """Counter(string)"""
    for i in range(iterations):
        Counter(string)

@time_me
def test_for(string, iterations, d):
    """for loop from cha0site"""
    for i in range(iterations):
        for c in string:
            if c in d:
                d[c] += 1

@time_me
def test_default_dict(string, iterations):
    """defaultdict from joaquin"""
    for i in range(iterations):
        mydict = defaultdict(int)
        for mychar in string:
            mydict[mychar] += 1

Test execution:

d_ini = dict((c, 0) for c in string.ascii_letters)
words = ['hand', 'marvelous', 'supercalifragilisticexpialidocious']

for word in words:
    print('-- {} --'.format(word))
    test_dict(word, 100000)
    test_set(word, 100000)
    test_counter(word, 100000)
    test_for(word, 100000, d_ini)
    test_default_dict(word, 100000)
    print()

print('-- {} --'.format('Pride and Prejudcie - Chapter 3 '))

test_dict(ch, 1000)
test_set(ch, 1000)
test_counter(ch, 1000)
test_for(ch, 1000, d_ini)
test_default_dict(ch, 1000)

Test results:

-- hand --
389.091 ms -  dict((c, string.count(c)) for c in string)
438.000 ms -  dict((c, string.count(c)) for c in set(string))
867.069 ms -  Counter(string)
100.204 ms -  for loop from cha0site
241.070 ms -  defaultdict from joaquin

-- marvelous --
654.826 ms -  dict((c, string.count(c)) for c in string)
729.153 ms -  dict((c, string.count(c)) for c in set(string))
1253.767 ms -  Counter(string)
201.406 ms -  for loop from cha0site
460.014 ms -  defaultdict from joaquin

-- supercalifragilisticexpialidocious --
1900.594 ms -  dict((c, string.count(c)) for c in string)
1104.942 ms -  dict((c, string.count(c)) for c in set(string))
2513.745 ms -  Counter(string)
703.506 ms -  for loop from cha0site
935.503 ms -  defaultdict from joaquin

# !!!: Do not compare this last result with the others because is timed
#      with 1000 iterations instead of 100000
-- Pride and Prejudcie - Chapter 3  --
155315.108 ms -  dict((c, string.count(c)) for c in string)
982.582 ms -  dict((c, string.count(c)) for c in set(string))
4371.579 ms -  Counter(string)
1609.623 ms -  for loop from cha0site
1300.643 ms -  defaultdict from joaquin
若言繁花未落 2025-01-04 13:45:25

Python 2.7+ 的替代方案:

from collections import Counter

abc = Counter('asdfdffa')
print abc
print abc['a']

输出:

Counter({'f': 3, 'a': 2, 'd': 2, 's': 1})
2

Alternative for Python 2.7+:

from collections import Counter

abc = Counter('asdfdffa')
print abc
print abc['a']

Output:

Counter({'f': 3, 'a': 2, 'd': 2, 's': 1})
2
笨笨の傻瓜 2025-01-04 13:45:25

这是集合模块的工作:


选项 1.- 集合。 defaultdict

>>> from collections import defaultdict
>>> mydict = defaultdict(int)

那么你的循环就变成:

>>> for mychar in mystring: mydict[mychar] += 1

选项2.- collections.Counter (来自 Felix 评论):

对于这种特定情况更好的替代方案,并且来自相同的 collections 模块:

>>> from collections import Counter

那么你只需要(!!!):

>>> mydict = Counter(mystring)

计数器仅在 python 2.7 中可用。所以对于 python < 2.7 你应该继续使用defaultdict

This is a job for the collections module:


Option 1.- collections. defaultdict:

>>> from collections import defaultdict
>>> mydict = defaultdict(int)

then your loop becomes:

>>> for mychar in mystring: mydict[mychar] += 1

Option 2.- collections.Counter (From Felix comment):

An alternative that is better for this specific case, and from the same collections module:

>>> from collections import Counter

then you only need (!!!):

>>> mydict = Counter(mystring)

Counter is only available from python 2.7. So for python < 2.7 you should stay with defaultdict

糖果控 2025-01-04 13:45:25

这不是列表理解的良好候选者。您通常希望使用列表推导式来创建列表,并且其中产生副作用(更改全局状态)并不是一个好主意。

另一方面,你的代码可能会更好,像这样:

for c in string:
    if c in dict:
        dict[c] += 1

或者如果你真的想获得功能(我已将 dict 重命名为 d 因为我需要 python 的内置 -在 dict 函数中):

d.update(dict([ (c, d[c]+1, ) for c in string ]))

请注意我如何没有在列表理解中更改 d,而是在外部更新了 d它的。

That's not a good candidate for a list comprehension. You usually want to use list comprehensions to make list, and to have side-effects (changing global states) in them is not such a good idea.

One the other hand, your code might be better off like this:

for c in string:
    if c in dict:
        dict[c] += 1

Or if you really want to get functional (I've renamed dict to d because I need python's built-in dict function):

d.update(dict([ (c, d[c]+1, ) for c in string ]))

Notice how I did not change d within the list comprehension, but instead updated d outside of it.

挥剑断情 2025-01-04 13:45:25

你原来的循环完全不符合 Python 风格。如果您只想迭代 string 中的字母,则无需迭代 range(len(string))。改为这样做:

for c in my_string:
    if c in my_dict:
        my_dict[c] += 1

Your original loop is hopelessly unPythonic. There's no need to iterate through range(len(string)) if all you want is to iterate through the letters in string. Do this instead:

for c in my_string:
    if c in my_dict:
        my_dict[c] += 1
你的背包 2025-01-04 13:45:25
>>> def count(s):
    global k
    list =[]
    for i in s:
        k=0
        if i not in list:
            list.append(i)      
            for j in range(len(s)):
                if i == s[j]:
                    k +=1

            print 'count of char {0}:{1}'.format(i,k)


>>> count('masterofalgorithm')
count of char m:2
count of char a:2
count of char s:1
count of char t:2
count of char e:1
count of char r:2
count of char o:2
count of char f:1
count of char l:1
count of char g:1
count of char i:1
count of char h:1
>>> 
>>> def count(s):
    global k
    list =[]
    for i in s:
        k=0
        if i not in list:
            list.append(i)      
            for j in range(len(s)):
                if i == s[j]:
                    k +=1

            print 'count of char {0}:{1}'.format(i,k)


>>> count('masterofalgorithm')
count of char m:2
count of char a:2
count of char s:1
count of char t:2
count of char e:1
count of char r:2
count of char o:2
count of char f:1
count of char l:1
count of char g:1
count of char i:1
count of char h:1
>>> 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文