【问题标题】:Python dictionaries adding different values to a key?Python字典向键添加不同的值?
【发布时间】:2014-04-09 08:47:08
【问题描述】:

我想创建一个函数,它遍历一个列表并创建一个字典,其中包含列表中每个事物的键以及列表中紧随键后的事物的值。

def function(s : str) -> {str:{str}}:
    listt=list(s)
    dictt= {}
    for i in listt[:-1]:
        if i not in dictt:
            dictt[i] = set()
        dictt[i].update(listt[listt.index(i)+1])
    return dictt



print(function('bookeeper'))

应该返回:

{'b': {'o'}, 'k': {'e'}, 'p': {'e'}, 'o': {'o', 'k'}, 'e': {'e', 'p', 'r'}}

但实际上返回:

{'b': {'o'}, 'k': {'e'}, 'p': {'e'}, 'o': {'o'}, 'e': {'e'}}

【问题讨论】:

标签: python dictionary


【解决方案1】:

不要使用list.index();只会匹配 first 出现的字母;对于'o',它永远不会找到第二个'o';您只会重复地将相同的字符添加到集合中。

改为使用enumerate() 为循环添加索引:

def function(s : str) -> {str:{str}}:
    listt=list(s)
    dictt= {}
    for next_index, char in enumerate(listt[:-1], 1):
        if char not in dictt:
            dictt[char] = set()
        dictt[char].update(listt[next_index])
    return dictt

我从 1 开始 enumerate() 而不是默认的 0,因此它始终代表 下一个 位置。

演示:

>>> def function(s : str) -> {str:{str}}:
...     listt=list(s)
...     dictt= {}
...     for next_index, char in enumerate(listt[:-1], 1):
...         if char not in dictt:
...             dictt[char] = set()
...         dictt[char].update(listt[next_index])
...     return dictt
... 
>>> print(function('bookeeper'))
{'p': {'e'}, 'o': {'o', 'k'}, 'e': {'p', 'r', 'e'}, 'b': {'o'}, 'k': {'e'}}

现在它可以工作了,让我们稍微简化一下;例如,当缺少键时,使用dict.setdefault() 将集合添加到字典中。字符串已经是序列,也不需要将它们转换为列表:

def function(s : str) -> {str:{str}}:
    dictt = {}
    for next_index, char in enumerate(s[:-1], 1):
        dictt.setdefault(char, set()).update(s[next_index])
    return dictt

除了enumerate(),我们还可以使用zip()来配对单词的字母:

def function(s : str) -> {str:{str}}:
    dictt = {}
    for char, next_char in zip(s, s[1:]):
        dictt.setdefault(char, set()).update(next_char)
    return dictt

【讨论】:

    【解决方案2】:

    您的问题是 index() 总是返回字符串中的第一个索引,因此您将一遍又一遍地将相同的字符添加到集合中。

    试试类似的东西

    def function(s : str) -> {str:{str}}:
        dictt = {}
        for pos, char in enumerate(s[:-1]):
            if char not in dictt:
                dictt[char] = set()
            dictt[char].update(s[pos+1])
        return dictt
    

    【讨论】:

    • ooooooooooooooooooooooooooooohhhhhhhh
    【解决方案3】:

    这是另一个答案:

    def func(string):
        arr = set(string)
        res = {}
        for char in arr:
            index = [i for i in range(len(string)) if string[i] == char]
            temp = []
            for i in index:
                if i == len(string) - 1:
                    continue
    
                temp.append(string[i + 1])
    
            if temp:
                res[char] = temp
    
        return res
    
    func('bookeeper')
    
    >>> {'b': ['o'], 'e': ['e', 'p', 'r'], 'k': ['e'], 'o': ['o', 'k'], 'p': ['e']}
    

    【讨论】:

    • 这会产生列表,而不是集合。例如,它会为toppop 产生错误的结果(o 之后的两次p)。
    • 效率也极低;您的算法使用 O(N^2) 时间;对于单词中的每个额外字符,您花费的时间会加倍。
    猜你喜欢
    • 2020-06-10
    • 1970-01-01
    • 2018-05-27
    • 2015-08-24
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多