从列表理解中获取匹配的子列表

时间:2014-11-30 15:12:28

标签: python list-comprehension python-2.x

cache = [['a', 'b'], ['c', 'd']]
val = 'a'
if val in [x for [x,y] in cache]:
    print(y)
else:
    print('Not found')

在上面的代码中,我希望将b作为答案返回。但是,结果是d。如何从此表达式中检索匹配的项目?请原谅我,如果我的术语不正确,我就开始学习Python和列表推导。我更喜欢使用这种速记符号,因为我还不熟悉lambda表达式。另一个好奇心,为什么结果为d

3 个答案:

答案 0 :(得分:2)

[x for [x, y] in cache]

这将创建一个临时列表['a', 'c'],您可以使用它来检查其中是否包含val。然而,列表永远不会被保留,因此您无法真正访问它。由于这是Python 2,因此列表中的变量(xy)实际上从表达式中泄漏出来,因此它们仍然存在。但是当您浏览cache时,它们将分别具有'c''d'的最后值。

>>> [x for [x, y] in cache]
['a', 'c']
>>> x, y
('c', 'd')

当然这并不是真的有用,而variable leaking has been fixed in Python 3(在列表理解之后两个变量都保持未定义)。

但要解决您的问题,您要执行的操作是从缓存中查找x,然后返回相应的y。您只需创建一个将x映射到y的字典:

即可
>>> d = {x: y for x, y in cache}
>>> d
{'a': 'b', 'c': 'd'}
>>> if val in d:
        print(d[val])
    else:
        print('Not found')

b

如果缓存总是包含两个元素的子列表,其中第一个元素用于查找事物,那么完全切换到字典是个好主意。这样,您可以在恒定时间内进行查找(这非常有用,因为您希望缓存速度很快),并且可以对其进行更多控制(例如避免重复/旧值)。

答案 1 :(得分:2)

问题是,在您查找[x for [x,y] in cache]之前,['a','c']表达式的值为a。因此,ab无关。

y包含d的值,因为它是迭代ycache中存储的最后一个值

我认为你想要的是这样的:

cache = [['a', 'b'], ['c', 'd']]
val = 'a'
ys = [y for [x,y] in cache if val == x]
if ys:
    print(ys[0])
else:
    print('Not found')

答案 2 :(得分:1)

这应该适用于列表理解。

[y for x,y in cache if x == val]