有效排序词典列表?

时间:2017-07-16 05:32:12

标签: python python-3.x

所以这是我到目前为止的尝试;我使用lambda之前的回答有问题,然后尝试了别的东西。我的第二种方法有效,但我想知道(如果和)为什么效率低下。修复也很好。

people = [
{'name': "Tom", 'age': 10},
{'name': "Mark", 'age': 5},
{'name': "Pam", 'age': 7}
]

# This did not work; I got '<filter object at 0x1020b7f28>' back, which I believe is the memory location itself.
result = filter(lambda person: person['name'] == 'Pam', people)
print(result)

# This is the attempt that works but looks very ugly.
def search(name):
    counter = 0
    for student in people:
        if student['name'] == name:
            print("{0} is {1} years old.".format(student['name'], student['age']))
            break
        else:
            counter += 1
    if counter == len(people):
        print("There are no students with that name.")

5 个答案:

答案 0 :(得分:1)

您不需要显式计数器变量。你知道,如果你到达最后没有找到匹配的名称,那么只有print()

def search(name):
    for student in people:
        if student['name'] == name:
            print("{0} is {1} years old.".format(student['name'], student['age']))
            return
    print("There are no students with that name.")

请注意,此解决方案仍为 O(n) - 与原始解决方案相同。正如@Erich所提到的,如果您想要一个 O(1) 的解决方案,请使用字典将每个人名称映射到他们的特定属性:

>>> people = {
'Tom': {'age': 10},
'Mark': {'age': 5},
'Pam': {'age': 7}
}
>>> def search(name):
    person = people.get(name, None)
    if person is not None:
        print("{0} is {1} years old.".format(name, person['age']))
    else:
        print("There are no students with that name.")


>>> search('Bobby')
There are no students with that name.
>>> search('Mark')
Mark is 5 years old.
>>> search('Timmy')
There are no students with that name.
>>> 

答案 1 :(得分:1)

整个方法可以概括为:

def search(name):
    try:
        student = next(i for i in people if i['name'] == name)
        print("{0} is {1} years old.".format(student['name'], student['age']))
        return True
    except StopIteration:
        return False

答案 2 :(得分:1)

首先,您的原始尝试确实有效,只是返回generator而不是列表。这样做的原因是过滤器可以被懒惰地评估(即,在你尝试迭代它之前不会完成任何工作)。以下内容将按您的意图使用。

result = list(filter(lambda person: person['name'] == 'Pam', people))

但是,我认为通过使用列表推导而不是过滤器可以稍微改进一下,因为您似乎希望对其进行评估。

result = [person for person in people if person.name == 'Pam']

答案 3 :(得分:0)

当你发现else返回False或者你可以返回名字或

时,

返回True

def search(name):
    counter = 0
    for student in people:
        if student['name'] == name:
            print("{0} is {1} years old.".format(student['name'], student['age']))
            return True

    return False

在重复名称返回列表或元组

的情况下
def search(name):
    name_list=[]
    for student in people:
        if student['name'] == name:
            print("{0} is {1} years old.".format(student['name'], student['age']))
            name_list.append((student['name'])

    return name_list

答案 4 :(得分:-1)

我相信每个条目都是它自己的对象,因为列表只存储指向字典的指针。因此,您无法真正知道列表是否包含O(1)时间内的名称,您至少需要O(n)。

如果你想使用更多的内存,你可以存储一组名称,但这只是一个快速包含,而不是快速访问。对此的用例将是许多不存在的查询。

如果您能够修改数据类型,我建议使用字典词典,其中键是每个人的姓名。这允许您在O(1)时间内访问目标人员的信息。

e.g。

my_dict = {
"Edward":{"age":10}
"Gerald":{"age":54}
"Rashim":{"age":23}
}

然后允许您执行以下操作:

my_dict["Rashim"]["age"]
>23

否则我认为您的解决方案可以在O(n)时间。