为什么在while循环中将字典值设置为零?

时间:2019-12-12 05:55:27

标签: python

我正在为面试做准备,想为字典中每个字母的计数制作字典。

我很惊讶地发现自己可能存在范围问题,或者似乎是一个问题。

对于下面的特定方法,我不确定为什么它不起作用,直到我发现在while循环中elem没有设置为空。但是由于它嵌套在引用elem的for循环中,所以我不确定为什么会发生这种情况。

s = 'letters and stuff'
def d_count(s):
    dic = {}
    i = 0
    s1 = set(s)
    s2 = list(s)
    for elem in s1:
        dic[elem] = 0
        j = 0
        while (i < len(s2)):
            #elem disappears here
            if s2[i] == elem:
                j = j+1
                dic[elem] = j
            i = i + 1
    return dic
print(d_count(s))

结果

{' ': 2, 's': 0, 'n': 0, 'u': 0, 'l': 0, 'f': 0, 'd': 0, 't': 0, 'r': 0, 'a': 0, 'e': 0}

所需结果

{' ': 2, 's': 2, 'n': 1, 'u': 1, 'l': 1, 'f': 2, 'd': 1, 't': 3, 'r': 1, 'a': 1, 'e': 2}

7 个答案:

答案 0 :(得分:3)

使用collections.Counter

from collections import Counter

s = 'letters and stuff'
c = Counter(s)
print(Counter(s))
# Counter({'t': 3, 'e': 2, 's': 2, ' ': 2, 'f': 2, 'l': 1, 'r': 1, 'a': 1, 'n': 1, 'd': 1, 'u': 1})

答案 1 :(得分:1)

代码存在的问题是,您需要在for循环中将i重置为零:

def d_count(s):
    dic = {}
    s1 = set(s)
    s2 = list(s)
    for elem in s1:
        i = j = dic[elem] = 0
        while (i < len(s2)):
            if s2[i] == elem:
                j += 1
                dic[elem] = j
            i += 1
    return dic

>>> print(d_count(s))
{' ': 2, 'r': 1, 'f': 2, 't': 3, 's': 2, 'a': 1, 'n': 1, 'd': 1, 'l': 1, 'e': 2, 'u': 1}

请注意,即使使用此修复程序,您的解决方案仍然是O(n**2),因为您需要完整浏览列表中的每个字符。

在访谈中使用Counter仅表明您知道自己可以使用它。面试官会期待一种不同的方法。这是O(n)这样的一种方法。

def d_count(s):
    d = {}
    for char in s:
        d[char] = d.get(char, 0) + 1
    return d

>>> print(d_count(s))
{'l': 1, 'e': 2, 't': 3, 'r': 1, 's': 2, ' ': 2, 'a': 1, 'n': 1, 'd': 1, 'u': 1, 'f': 2}

这是使用defaultdict的另一种方法,它也是O(n)

from collections import defaultdict

def d_count(s):
    dd = defaultdict(int)
    for char in s:
        dd[char] += 1
    return dict(dd)

>>> print(d_count(s))
{'l': 1, 'e': 2, 't': 3, 'r': 1, 's': 2, ' ': 2, 'a': 1, 'n': 1, 'd': 1, 'u': 1, 'f': 2}

答案 2 :(得分:0)

您可以执行以下操作:

 for elem in s1:
    dic[elem] = 0
    j = 0
    elem_copy = elem
    while (i < len(s2)):
        if s2[i] == elem_copy:
            j = j+1
            dic[elem_copy] = j
        i = i + 1

答案 3 :(得分:0)

尝试一下:

d = {i: s.count(i) for i in s}

答案 4 :(得分:0)

s = 'letters and stuff'
def d_count(s):
    dic = {}

    for element in s:
        dic[element] = s.count(element)
        set(dic)

    return dic
print(d_count(s))

输出:{'l':1,'e':2,'t':3,'r':1,'s':2,'':2,2,'a':1,'n' :1,'d':1,'u':1,'f':2}

答案 5 :(得分:0)

遵循"Easier to ask for forgiveness than permission" mantra的另一种解决方案,基本上模仿了defaultdict的功能:

s = 'letters and stuff'
d = {}
for c in s:
    try:
        d[c] += 1
    except KeyError:
        d[c] = 1
print(d)
# {'l': 1, 'e': 2, 't': 3, 'r': 1, 's': 2, ' ': 2, 'a': 1, 'n': 1, 'd': 1, 'u': 1, 'f': 2}

或者检查密钥是否存在:

s = 'letters and stuff'
d = {}
for c in s:
    if c in d:
        d[c] += 1
    else:
        d[c] = 1
print(d)
# {'l': 1, 'e': 2, 't': 3, 'r': 1, 's': 2, ' ': 2, 'a': 1, 'n': 1, 'd': 1, 'u': 1, 'f': 2}

答案 6 :(得分:-1)

我还没有弄清楚为什么这行不通。但是,如果有帮助,就可以解决问题并提供所需的结果

s = 'letters and stuff'
def d_count(s):
    dic = {}
    s1 = set(s)
    s2 = list(s)
    for elem in s1:
        dic[elem] = 0
        j = 0
        for i in xrange(0,len(s2)):
            if s2[i] == elem:
                j = j+1
                dic[elem] = j
    return dic
print(d_count(s))