递增 dict 系统的列表(应该很简单)

Posted

技术标签:

【中文标题】递增 dict 系统的列表(应该很简单)【英文标题】:list to incrementing dict system (should be simple) 【发布时间】:2021-01-12 17:48:44 【问题描述】:

我正在尝试创建一个将列表转换为字典的系统。键应该是列表中的项目,而每个唯一键的值应该是递增的数字(1、2、3、4 等)。

期望的结果:

Input:
list = ["Ford", "Ford", "Chevy", "Chevy", "Chevy", "Honda", "Honda", "Honda", "Honda"]

Output:
dict = 
  "Ford": 1,
  "Ford": 1,
  "Chevy": 2,
  "Chevy": 2,
  "Chevy": 2,
  "Honda": 3,
  "Honda": 3,
  "Honda": 3,
  "Honda": 3,

我尝试使用它,因为它可以让我从 0 开始并递增。它最终没有工作。

dict = 
list = []
for x, index in list:
  if x not in list:
      dict[x] = len(dict)

这是我得到的错误:

ValueError: too many values to unpack (expected 2)

谁能帮忙?

【问题讨论】:

字典中不能有重复的键;您想要的输出 t 是不可能的。 几个问题: 1. 您应该在索引时使用enumerate 迭代列表,然后顺序为index, element 2. 您正在迭代list(这是一个错误的变量name BTW) 然后if 检查该元素是否在列表中not。这个检查没有意义。 3. 字典中不能有重复的键 @MarkMeyer 无论如何都有一个键和该键的多个值 @MarkMeyer 我想我想要一个键,然后是一个值列表 @MarkMeyer 你能帮我吗 【参考方案1】:

意识到你不能在字典中有重复的键。

使用setenumerate 和字典理解的组合。

v:i for i,v in enumerate(set(l))

示例结果:

'Honda': 0, 'Chevy': 1, 'Ford': 2

请不要使用dictlist 作为变量名,因为您会隐藏dictlist 内置函数。

【讨论】:

@DeepSpace,我的错。谢谢 Netwave 这不允许我处理本田或雪佛兰的多个实例 也许本田:[0,0,0,雪佛兰:[1,1,1] 会更好【参考方案2】:

您可以使用变量而不是 len(dict) 并检查字典是否已经有键或没有相应地添加键、值对

dict=
list=["Ford", "Ford", "Chevy", "Chevy", "Chevy", "Honda", "Honda", "Honda", "Honda"]
count=1
for i in list:
    if i in dict:
        continue
    dict[i]=count
    count+=1
print(dict)

【讨论】:

在原帖上查看我的 cmets,我想你是否可以编辑它【参考方案3】:

您收到的 ValueError 是因为 for x, index in list: 无效。列表的迭代器只会返回一个对象,即列表中的值。如果要同时获取元素的索引和元素,则需要enumerate。但是,这不一定是获取用于汽车名称的索引的最佳方式。另外,按照 DeepSpace 和 Netwave 的建议,我使用的变量名也不是 Python 关键字。

cars_list = ["Ford", "Ford", "Chevy", "Chevy", "Chevy", "Honda", "Honda", "Honda", "Honda"]
cars_dict = 
for car_name in cars_list:
    cars_dict.setdefault(car_name, len(cars_dict))

如果car_name 尚未作为键存在,setdefault 将设置cars_dict[car_name] 的值,但如果car_name 已经存在,则不会更改该值。 len(cars_dict) 将是钥匙的数量,因此当您添加新车时,它将是一个以前未使用过的值。

这仍然不会产生带有重复键的字典,但是:

print(cars_dict)
# yields 'Ford': 0, 'Chevy': 1, 'Honda': 2

【讨论】:

这不允许我处理本田或雪佛兰的多个实例 也许本田:[0,0,0,雪佛兰:[1,1,1] 会更好?【参考方案4】:

如果您有一个排序列表(就像您在示例中所做的那样),您可以使用 itertools groupby()count() 很好地做到这一点。 count() 创建一个递增的迭代器,可以增加您使用它的时间。当您将其与组一起压缩时,您可以为列表中的每个组使用一个递增的数字。

from itertools import groupby, count

l = ["Ford", "Ford", "Chevy", "Chevy", "Chevy", "Honda", "Honda", "Honda", "Honda"]

d = 
for cnt, (k, v) in zip(count(1), groupby(l)):
    d[k] = [cnt] * len(list(v))

d 将是:

'Ford': [1, 1], 'Chevy': [2, 2, 2], 'Honda': [3, 3, 3, 3]

如果这个列表没有排序,你可以简单地先排序。

【讨论】:

我该如何排序? sorted(l) 将按排序顺序返回l 的副本,同时保持l 不变,l.sort() 将修改l 以对其进行排序。 我不太确定用例是什么,但我个人不确定我是否喜欢使用[3, 3, 3, 3] 表示“Honda 具有 ID 3 和在原始列表中出现四次”。如果我们只想跟踪Honda 出现的次数,我们不妨只存储数字而不是存储那么多元素的列表。所以像'Honda': (3, 4) 甚至'Honda': 'ID': 3, 'count': 4 这样的东西是为了可读性。 很公平@NathanPierson,我只是在回答 cmets 中提出的问题。我不知道预期的用例是什么。希望很明显len(list(v)) 给出了项目的数量,cnt 是组索引。感谢您添加sort() 澄清。 哦,当然。只是提出一些设计供@Juliette 考虑,真的。您的代码很容易修改以生成底层收集信息的不同表示。

以上是关于递增 dict 系统的列表(应该很简单)的主要内容,如果未能解决你的问题,请参考以下文章

递增列表中的列表(封装列表)

检查给定键是不是已存在于字典中并将其递增

面试题——递增间隔分割列表

什么会导致for循环在它应该递增时递减?

使用 ViewModel 和 LiveData 递增变量的简单片段示例 - 变量始终为空

使用 itertools 将列表拆分为递增的序列