【问题标题】:Iterating over dict values迭代dict值
【发布时间】:2024-05-29 14:10:01
【问题描述】:

如果我想遍历存储在元组中的字典值。

我需要返回持有“CI”值的对象,我假设我需要某种 for 循环:

z = {'x':(123,SE,2,1),'z':(124,CI,1,1)}
for i, k in db.z:
    for k in db.z[i]:
        if k == 'CI':
            return db.z[k]

我可能在这里遗漏了一些东西,一个参考点会很好。

如果有更快的方法这样做,这一切都会有很大帮助

【问题讨论】:

  • 什么是 SE 和 CI 变量或字符串??

标签: python python-3.x dictionary


【解决方案1】:

遍历字典的方法

首先,有几种方法可以遍历字典。

直接在字典上循环:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for key in z:
...     print key,
...
'x' 'z'

请注意,当您遍历字典时返回的循环变量是键,而不是与这些键关联的值。

遍历字典的值:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for value in z.values(): # Alternatively itervalues() for memory-efficiency (but ugly)
...     print value,
...
(123,'SE',2,1) (124,'CI',1,1)

循环遍历键和值:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> for key, value in z.items(): # Again, iteritems() for memory-efficiency
...     print key, value,
...
'x' (123,'SE',2,1) 'z' (124,'CI',1,1)

后两者比循环遍历键并运行 z[key] 来获取值更有效。它也可以说更具可读性。

在这些基础上...

列表理解

List comprehensions 很棒。 对于仅搜索“CI”的简单情况:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> [key for key, value in z.items() if 'CI' in value]
['z']

用于查找包含多个搜索项的 dict 键:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 1) # Only keys that hold both CI and 1 will match
>>> [key for key, value in z.items() if all(item in value for item in search_items)]
['z']

用于查找包含多个搜索项的字典键:

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 'SE', 'JP') # Keys that hold any of the three items will match
>>> [key for key, value in z.items() if any(item in value for item in search_items)]
['x', 'z']

如果后两者作为单行代码看起来有点过于复杂,您可以将最后一位重新编写为单独的函数。

>>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
>>> search_items = ('CI', 'SE', 'JP') # Keys that hold any of the three items will match
>>> def match_any(dict_value, search_items):
...     return any(item in dict_value for item in search_items)
...
>>> [key for key, value in z.items() if match_any(value, search_items)]
['x', 'z']

一旦你习惯了 [x for x in iterable if condition(x)] 语法,该格式应该很容易阅读和遵循。

【讨论】:

  • itervalues() 不再受支持。看起来 values() 是要走的路
【解决方案2】:
z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for i in z.keys(): #reaching the keys of dict
    for x in z[i]: #reaching every element in tuples
        if x=="CI": #if match found..
            print ("{} holding {}.".format(i,x)) #printing it..

这可能会解决您的问题。

输出:

>>> 
q holding CI.
>>> 

编辑您的评论:

def func(*args):
    mylist=[]
    z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
    for x,y in z.items():
        for t in args:
            if t in y:
                mylist.append(x)
    return mylist
print (func(1,"CI"))

输出:

>>> 
['q', 'q', 'x']
>>>  

希望这是你想要的,否则第一种方法已经打印了所有键,示例输出:

if x==1 or x=="CI":

>>> 
x holding 1.
q holding CI.
q holding 1.
q holding 1.
>>> 

【讨论】:

  • 不需要打印需要退货:)
  • 我只是打印它然后你可以确定它是你想要的,我假设你会将它更改为 return 抱歉:)
  • 如果需要在键中查找 n 个值,我将如何更改代码?我的意思是如果我需要找到一个同时保存 CI 和 1 的密钥然后返回它?我会假设我需要另一个值来检查/
  • 在python 2.x中,使用for i in z:而不是for i in z.keys():更简洁高效。
【解决方案3】:

如果您只对值感兴趣,则无需检索密钥:

在 Python 2.x 中:

z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for value in z.itervalues():
    if 'CI' in value:
        return value

在 Python 3.x 中:

z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
for value in z.values():
    if 'CI' in value:
        return value

【讨论】:

    【解决方案4】:

    试试这个:

    >>> z = {'x':(123,'SE',2,1),'z':(124,'CI',1,1)}
    >>> list(filter(lambda x:'CI' in z.get(x),z))
    ['z']
    

    【讨论】:

    • 我最喜欢这种功能性方法。不仅更简洁,而且不做任何修改支持 no (empty list) 到多个匹配。
    • 我必须同意你的观点,但它对我来说很复杂,无法理解它是如何工作的,我只是一个初学者,所以我选择迭代方法。
    【解决方案5】:
    z = {'x':(123,"SE",2,1),'q':(124,"CI",1,1)}
    for key, val in z.items():
        if 'CI' in val:
            return z[key]
    

    【讨论】: