【问题标题】:How can I iterate through a dictionary whose length changes in python?如何遍历长度在 python 中发生变化的字典?
【发布时间】:2019-05-08 10:10:17
【问题描述】:

我有一本字典,我想遍历并更改其值,但我认为更改长度可能会导致错误,有什么好的方法可以做到这一点吗?

示例:

d = {'a':'orange','b':'pineapple','c':'dragonfruit'}
rating = {'orange':3, 'pineapple':4, 'dragonfruit':4.5, 'apple':3, 'pear': 3.5}

for key, value in d.items():
    if some conditions met:
        del d['a'] or d['e']='apple' # (or is not operator, i mean literally one of the operation add or delete item...)

例如:

for key, value in d.items():
    if rating[value]<4:
        del d[key]

d = {'a':['orange'],'b':['pineapple','peach'],'c':['dragonfruit']}
rating = {'orange':3, 'pineapple':4, 'dragonfruit':4.5, 'apple':3, 'pear': 3.5, 'peach': 5}
for key, value in d.items():
    rating_sum = sum([ rating[v] for v in value])
    if rating_sum > 8 and len(value)>1:
        d['e'] = d[key].pop(-1)

可能不是最好的例子...意味着字典的长度在循环中发生变化。

【问题讨论】:

  • 我假设最后一行是伪代码?
  • 。不要这样做。做一个听写理解:d2 = dict(k,v) for k in d if not cond(k)@jpp 说。
  • @zvone:另一个问题有点不同,它更多的是询问“为什么在迭代时删除项目会在字典而不是列表上给出错误?”而这个问题是“我怎样才能在字典上真正做到这一点?”
  • @smci 如果一个问题是“为什么我不能做X”,另一个是“我该怎么做X”,那么它们是相同的,因为两者的答案都是“不要做X,而是做Y”

标签: python dictionary iteration


【解决方案1】:

在迭代字典时不要添加或删除键。另外,不要隐藏内置的dict

您可以在所有条件下使用字典推导:

d = {k: v for k, v in d.items() if \
     not (conditions and \
     ((k == 'a') or ((k, v) == ('e', 'apple'))))}

我假设您的 conditionskv 的函数,否则您应该在字典理解之外计算和应用此测试。

但这可能会有点混乱,所以将你的逻辑分离成一个函数并没有什么坏处:

def keep_pair(k, v):
    if conditions:
        if (k == 'a') or ((k, v) == ('e', 'apple')):
            return False
    return True

d = {k, v for k, v in d.items() if keep_pair(k, v)}

【讨论】:

  • 我认为这是最好的答案,但它是否与del dict['a'] or dict['e']='apple' 行一样?看起来您将复制原始字典,应用条件并始终删除键 'a' 和 'e',apple。
  • @TylerMarshall,我已经更新了我的答案,我 认为 符合 OP 的要求。 del dict['e'] = 'apple' 本身没有任何意义。您不能删除分配,您可以做的是根据键和值删除。
  • 对不起,我的意思是 dict['e'] = 'apple' 通过添加一个项目
  • @raffa,需要更清楚一点,conditions 是什么,它是kv 的函数吗?如果是这样,你为什么要设置d['e'] = 'apple'多次?如果可能,请通过editing your question 提供完整 minimal reproducible example
  • @jpp 编辑了一下,条件是 v 的函数,实际上更复杂,我试着放 2 个简化的例子。谢谢
【解决方案2】:

您可以将您的 dict 复制到某个临时 dict 变量,然后遍历临时 dict 但对原始 dict 进行更改。

temp = dict.copy()

for key, value in temp.items():
    if some conditions met:
        del dict['a'] or dict['e']='apple'

【讨论】:

  • 这对于小型词典来说很好,对于较大的词典来说内存效率低下。除了使用dict 作为变量名,你应该永远这样做。
【解决方案3】:

不要。这并非不可能,但在大多数情况下,没有理由不构建新字典并重新分配名称,这样更易​​于书写和阅读。

d = <SOME-DICT>
# filter d with dict comprehension, reassign the name d
d = {k:v for k,v in d.items() if <FILTERING-CONDITION>}

一些演示::

>>> d = {'a':'orange','b':'pineapple','c':'dragonfruit'}
>>> {k:v for k,v in d.items() if v != 'pineapple'}
{'a': 'orange', 'c': 'dragonfruit'}
>>> {k:v for k,v in d.items() if not (k == 'd' and v == 'dragonfruit')}
{'a': 'orange', 'b': 'pineapple', 'c': 'dragonfruit'}
>>> {k:v for k,v in d.items() if not (k == 'c' and v == 'dragonfruit')}
{'a': 'orange', 'b': 'pineapple'}
>>> {k:v for k,v in d.items() if not (k == 'a' or (k == 'e' and v == 'pineapple'))}
{'b': 'pineapple', 'c': 'dragonfruit'}

【讨论】:

    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 2023-03-29
    • 2012-07-07
    相关资源
    最近更新 更多