使用Python如何根据内部列表的一个元素作为键,在一个列表的列表中查找元素?

17
假设我有一个列表的列表或者一个元组的列表,无论哪个在解决我的问题时更有效率。例如:
student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]

任务是基于内部列表或元组中的任何元素,找到主列表中的一个元素作为关键字。

例如,使用上面的列表:

find(student_tuples, 'A')
或者
find(student_tuples, 15)

两者都会返回

('john', 'A', 15)

我正在寻找一种高效的方法。


你应该考虑创建一个“学生”类,并让你的学生列表包含该类的实例。 - Daenyth
4个回答

17

我会使用filter()或列表推导来解决这个问题。

def find_listcomp(students, value):
    return [student for student in students if student[1] == value or student[2] == value]

def find_filter(students, value):
    return filter(lambda s: s[1] == value or s[2] == value, students) 

你可以通过将返回值更改为:return [student for student in students if value in student] 来改进它。否则,它只会返回元组中第二个和第三个值的匹配结果。 - Matt Howell
@bigmattyh:如果value == 'john',那么它会返回('john'...),这不是OP想要的。 - Daenyth
他说:“任务是基于内部列表或元组的任何元素,找到主列表中的一个元素。” - Matt Howell
我将结合您的第二个解决方案和@sverre提供的解决方案,得到:return filter(lambda s: value in s, students) - kadam

10

要仅查找第一个匹配项,您可以使用

def find(list_of_tuples, value):
    return next(x for x in list_of_tuples if value in x)

如果找不到匹配记录,这将引发StopIteration。为了引发更合适的异常,您可以使用
def find(list_of_tuples, value):
    try:
        return next(x for x in list_of_tuples if value in x)
    except StopIteration:
        raise ValueError("No matching record found")

4
您可以使用Python的列表推导式来选择和筛选内容:
def find(tuples, term):
    return [tuple for tuple in tuples if term in tuple]

1
我喜欢这个,但是它有一个错别字:if term in tuples 应该改为 if term in tuple - kadam
正如我在@Daenyth的解决方案中所评论的那样,我将结合你们两个人的答案。两个答案都很好,我接受了另一个,因为它更早到达。 - kadam

0

这个函数将返回一个包含您搜索项的元组列表。给你:

def find_in_tuples(tuples, term):
    matching_set = []
    for tuple in tuples:
        if term in tuple:
            matching_set.append(tuple)
    return matching_set

>>> find_in_tuples(student_tuples, 'A')
[('john', 'A', 15)]
>>> find_in_tuples(student_tuples, 'B')
[('jane', 'B', 12), ('dave', 'B', 10)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接