基于值获取密钥列表时,当存在多个值时.

2024-10-03 15:35:22 发布

您现在位置:Python中文网/ 问答频道 /正文

当每个键有多个值时,如何基于一个值获得键列表?你知道吗

当值是单个对象时,下面的代码可以得到一个列表。但是,当有多个对象作为值或值中有其他数据时,它无法获取键。你知道吗

mydict = {
    'romeo': 16,
    'juliette': 16,
    'zena': 'red', 
    'gabby': 'red', 
    'lauren': 'smart',
    'betty': 'smart',
    'kristen': 'sweet',
    'lisa': 'sweet',
    'lucy': ['smart', 'sweet'],
    'shawna': 'green field', 
    'terry' : 'the green field is on fire', 
    'dorothy': 'shelly plays on the green field',
    'jenny': ['intelligent', 'cuts the smart green field grass'], 
}

needle = 'green field'
filtered_keys = [k for k, v in mydict.items() if v == needle]
print(filtered_keys)

needle = 16时,输出正确:['romeo', 'juliette']。你知道吗

needle = 'red'时,输出正确:['zena', 'gabby']。你知道吗

needle = 'smart'时,输出不正确:['lauren', 'betty']
预期的输出是['lauren', 'betty', 'lucy', 'jenny']。你知道吗

needle = 'sweet'时,输出不正确:['kristen', 'lisa']
预期的输出是['kristen', 'lisa', 'lucy']。你知道吗

needle = 'green field'时,输出不正确:['shawna']
预期的输出是['shawna', 'terry', 'dorothy', 'jenny']。你知道吗


Tags: thefield列表smartgreenredsweetlisa
2条回答

你有几个选择。我最初建议您将所有dict值包装在一个列表中。所以你的dict应该是:

mydict = {'romeo':[16],
    'juliette':[16],
    'zena': ['red'], 
    'gabby': ['red'], 
    'lauren': ['smart'],
    'betty': ['smart'],
    'kristen': ['sweet'],
    'lisa': ['sweet'],
    'lucy': ['smart', 'sweet'],
    'shawna': ['green field'], 
    'terry' :['the green field is on fire'], 
    'dorothy' :['shelly plays on the green field'],
    'jenny': ['intelligent', 'cuts the smart green field grass'], 
    }

然后你的列表会是这样的:

list_keys = [key for key, val in mydict.items() if lvalue in val]

另一个选项是测试dict中的值是什么类型。我不建议这样做,但如果你的情况不允许以前的解决方案,这可能会工作。所以你的列表应该是这样的:

list_keys = [key for key, val in mydict.items() if (type(val)==list and lvalue in val) or lvalue==val]

这里的问题是,如果您的dict值曾经获得过其他类型的iterable,那么您必须更改代码以检查这些其他iterable类型。仅仅检查这个值是否是iterable是行不通的,因为当你检查这个值时,你会遇到其他的问题。像'green' in 'green sleeves'评估到True这样的东西,尽管(根据你在问题中所展示的),我认为你会希望它评估到False。你知道吗

另一个答案不处理needlein一个字符串,而in是一个列表的情况。也就是说,另一个答案只在needle等于该值或该值直接包含时处理。因此,另一种解决方案在问题中包含的测试用例中不起作用。你知道吗

一般来说,可以递归地检查值是否包含needle。你知道吗

from typing import Any
from typing import Dict
from typing import Iterable

def keys_containing_value(d: Dict, needle: Any):
    def recursively_in(x: Any, n: Any):
        if isinstance(x, str) and isinstance(n, str):
            return n in x
        if type(x) is type(n):
            return x == n
        if isinstance(x, Iterable) and not isinstance(x, str):
            return any(recursively_in(item, n) for item in x)
    return [k for k, v in d.items() if recursively_in(v, needle)]

下面是该函数如何使用您的数据和测试用例:

mydict = {
    'romeo': 16,
    'juliette': 16,
    'zena': 'red',
    'gabby': 'red',
    'lauren': 'smart',
    'betty': 'smart',
    'kristen': 'sweet',
    'lisa': 'sweet',
    'lucy': ['smart', 'sweet'],
    'shawna': 'green field',
    'terry': 'the green field is on fire',
    'dorothy': 'shelly plays on the green field',
    'jenny': ['intelligent', 'cuts the smart green field grass'],
}
needles = [
    16,
    'red',
    'smart',
    'sweet',
    'green field',
]

for needle in needles:
    print(keys_containing_value(mydict, needle))

输出:

['romeo', 'juliette']
['zena', 'gabby']
['lauren', 'betty', 'lucy', 'jenny']
['kristen', 'lisa', 'lucy']
['shawna', 'terry', 'dorothy', 'jenny']

相关问题 更多 >