繁体   English   中英

检查字典列表中是否已经存在值,以及它是否更新了计数器

[英]Check if value already exists within list of dictionaries and if it does update the counter

这是一个示例字典。 原始字典有更多的键。 我没有包括它们,因为它是不必要的混乱。 这本词典只是我问题的基本表示。

我有一个字典列表,如下所示:

colour_dict = [
    {'main_colour': 'red', 'count': 1},
    {'main_colour': 'blue', 'count': 5},
    {'main_colour': 'green', 'count': 10},
]

和颜色列表,如下:

colours = ["blue", "blue", "red", "greed", "red", "black"]

当我迭代颜色列表时,我想检查列表颜色中的颜色是否已经存在于字典colour_dict列表中。 如果确实存在,则将计数加 1,如果不存在,则将其添加到字典中。

这是我到目前为止所得到的:

for colour in colours:
    if any(d['main_colour'] == colour for d in colour_dict):
        #Increase counter of that colour
    else:
        colour_dict.append({
            'main_colour': colour, 'count': 1
        })

如果您需要您的数据采用您显示的格式,并且不想为每次添加都产生迭代该列表的成本,那么这不是问题。 您所要做的就是为该数据结构建立一个索引。 索引将是一个映射,键是颜色,值是原始结构中该颜色的索引。 您首先构建此索引,然后使用它来有效地处理新条目。 这是怎么回事:

colour_dict = [
    {'main_colour': 'red', 'count': 1},
    {'main_colour': 'blue', 'count': 5},
    {'main_colour': 'green', 'count': 10},
]

colours = ["blue", "blue", "red", "greed", "red", "black"]

# Build an index mapping colors to positions in the 'colour_dict' list
index = {}
for i, entry in enumerate(colour_dict):
    index[entry['main_colour']] = i


# Iterate over the new values, tallying them in the original structure, and
# adding new entries to both the original structure and the index when
# we discover colors that aren't yet in our structure.  Note that there
# is just a single lookup per addition to the structure.  No per-addition
# iteration here.
for colour in colours:
    if colour in index: 
        colour_dict[index[colour]]['count'] += 1
    else:
        index[colour] = len(colour_dict)
        colour_dict.append({'main_colour': colour, 'count': 1})

# Show the updated original structure
print(colour_dict)

结果:

[
    {'main_colour': 'red', 'count': 3},
    {'main_colour': 'blue', 'count': 7},
    {'main_colour': 'green', 'count': 10},
    {'main_colour': 'greed', 'count': 1},
    {'main_colour': 'black', 'count': 1}
]

我是一名编程老师,我认为这个问题是一个强调经常被忽视的技术的机会。 您不必更改现有的数据结构,该结构无法有效地查找内容,以便能够有效地在其中查找内容。 您可以在该结构中构建一个索引,该索引可以有效地查找指向原始结构进行存储的内容。 这是一种“有你的蛋糕,也有吃它”的情况。 它值得掌握,这样你就可以把它放在你的技巧包里。

这就像在书的后面维护一个索引,而不是重组书的内容,以便更容易地搜索单个概念,但代价是从头到尾阅读的价值降低。 书籍索引同样可以让您两全其美。

您的代码看起来不错,只是缺少计数增加的部分。 这是完整的代码:

for colour in colours:
    if any(d['main_colour'] == colour for d in colour_dict):
        for i in range(len(colour_dict)):
            if colour in colour_dict[i].values():
                colour_dict[i]['count']+=1
    else:
        colour_dict.append({
            'main_colour': colour, 'count': 1
        })

给定数据的结果:

>>> print(colour_dict)

[{'main_colour': 'red', 'count': 3}, {'main_colour': 'blue', 'count': 7}, {'main_colour': 'green', 'count': 10}, {'main_colour': 'greed', 'count': 1}, {'main_colour': 'black', 'count': 1}]

直接(但不是很快)的代码可能是:

for colour in colours:
    for dic in colour_dict:
        if dic['main_colour'] == colour:
            dic['count'] += 1
            break
    else:
        colour_dict.append({'main_colour': colour, 'count': 1})

结果:

 [{'main_colour': 'red', 'count': 3}, {'main_colour': 'blue', 'count': 7}, {'main_colour': 'green', 'count': 10}, {'main_colour': 'greed', 'count': 1}, {'main_colour': 'black', 'count': 1}]

说明:

只有当循环完全耗尽时才会执行for循环的else分支,即如果没有 break 语句提前完成它。

这是我能想到的最好的方法。 它只对每种颜色的字典列表迭代一次。

for colour in colours:
    c_dict = list(filter(lambda c: c['main_colour']==colour, colour_dict))

    # if it exists c_dict points at the actual value within the colour_dict list
    # This means c_dict can be simply updated
    if len(c_dict) != 0:
        c_dict[0]['count'] += 1
    else:
        colour_dict.append({'main_colour':colour, 'count':1})

如果您以不同的方式构建数据,它将更易于使用。 您还可以查看标准库的defaultdict

from collections import defaultdict
colour_dict = defaultdict(int) # produces int() == 0 on entry creation
colour_dict.update({
    'red': 1,
    'blue': 5,
    'green': 10,
})
colours = ["blue", "blue", "red", "greed", "red", "black"]
for c in colours:
    colour_dict[c] += 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM