查找多个列表中是否存在值

时间:2016-01-14 06:34:34

标签: python list

我有4个列表,列表中的每个元素在4个列表中都是唯一的。如何查找其中一个列表中是否存在该值并返回它所在的列表?

示例列表:

value = 'a'
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']

我的预期输出是找到值的列表的名称: 对于上面的例子,我的预期输出是:

4 个答案:

答案 0 :(得分:7)

您可以使用list comprehension

>>> value ="a"
>>> a = ['a','b','c']
>>> b = ['d','e','f']
>>> d = ['g','h','i']
>>> c = ['j','k','l']
>>> [x for x in a,b,c,d if value in x]
[['a', 'b', 'c']]

获取变量名称:

>>> for x in a,b,c,d:
...     if value in x:
...         for key,val in locals().items():
...             if x == val:
...                 print key
...                 break
... 
a
  
    

locals()包含本地范围变量作为字典,变量名称为键,其值为值

         

globals包含全局范围变量作为字典,变量名称为键,其值为值

  

答案 1 :(得分:3)

如果你不想使用列表理解,你总是可以使用一个复杂而冗长的lambda表达式!

list(filter(lambda x: value in x, [a,b,c,d]))

编辑:问题已更新,要求输入var名称,而不是var值

答案 2 :(得分:2)

鉴于您的更新问题,我们假设a, b, c, d变量属于全球范围

value = 'a'
a = ['a','b','c']
b = ['d','e','f']
d = ['g','h','i']
c = ['j','k','l']

w = next(n for n,v in filter(lambda t: isinstance(t[1],list), globals().items()) if value in v)
print(w)

产生

a

即。包含value

的全局命名空间中第一个列表的名称

如果变量在本地范围内,例如在函数中,您可以使用locals()代替

def f():
    a = ['a','b','c']
    b = ['d','e','f']
    d = ['g','h','i']
    c = ['j','k','l']
    w = next(n for n,v in filter(lambda t: isinstance(t[1],list), locals().items()) if value in v)
    print(w)

f()

产生

a

注意:您可能希望采用命名约定来定位特定的变量组,例如: targ_作为前缀

targ_a = ['a','b','c']
targ_b = ['d','e','f']
targ_d = ['g','h','i']
targ_c = ['j','k','l']
w = next(n for n,v in filter(lambda t: isinstance(t[1],list) and t[0].startswith('targ_'), globals().items()) if value in v)
print(w)

产生

targ_a

为了更详细地解释一下,让我们看一下globals()调用返回的内容。例如,使用python shell

Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> value = 'a'
>>> targ_a = ['a','b','c']
>>> targ_b = ['d','e','f']
>>> targ_d = ['g','h','i']
>>> targ_c = ['j','k','l']
>>> globals()
{'targ_d': ['g', 'h', 'i'], 'targ_c': ['j', 'k', 'l'],
 '__builtins__': <module 'builtins' (built-in)>,
 '__doc__': None, '__package__': None,
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 'targ_a': ['a', 'b', 'c'], '__name__': '__main__',
 'targ_b': ['d', 'e', 'f'], '__spec__': None, 'value': 'a'}

如您所见,globals()返回字典。其键是全局命名空间中定义的变量的名称。它的值是每个这样的变量所持有的值。

因此

>>> next(n for n,v in filter(lambda t: isinstance(t[1],list) and t[0].startswith('targ_'), globals().items()) if value in v)
'targ_a'

在表达式生成的生成器上迭代一次,这将在全局名称空间中生成每个名称,该名称对应于名称以targ_开头并且包含等于value的元素的列表。它通过迭代调用globals

返回的字典来实现

答案 3 :(得分:2)

你要做的事几乎总是一个坏主意。假设您确实获得了一个包含所需列表名称的字符串。那你怎么办呢?如果您拥有的是包含其名称的字符串,那么获取变量没有好办法。您可以使用globals()locals()执行此操作,但这些不可避免地会使您的代码变得混乱和混乱。

执行此操作的正确方法是使用列表或字典来收集要搜索的所有列表。迭代单个对象比迭代全局或局部范围中的每个名称都要好得多。

value = "a"
named_lists = {
    "a": ['a','b','c'],
    "b": ['d','e','f'],
    "d": ['g','h','i'],
    "c": ['j','k','l']
}

names = [name for name, seq in named_lists.items() if value in seq]
print(names)
if names: #there may be multiple lists that contain `value`, so let's just look at the first one, if it exists
    first_name = names[0] 
    print(named_lists[first_name])

结果:

['a']
['a', 'b', 'c']