2017-02-03 76 views
1

比方说,我有对象名单:Python:如何查询对象列表?

listt = [{ 
     "CustomerId": "1", 
     "Date": "2017-02-02", 
     "Content": "AAAAAAAA", 
     "Type": 2 
    }, 
    { 
     "CustomerId": "2", 
     "Date": "2017-02-03", 
     "Content": "BBBBBBBB", 
     "Type": 1 
    }, 
    { 
     "CustomerId": "3", 
     "Date": "2017-02-01", 
     "Content": "CCCCCCCCC", 
     "Type": 1 
    }, 
    { 
     "CustomerId": "4", 
     "Date": "2017-02-12", 
     "Content": "DDDDDDDDDD", 
     "Type": 2 
    }, ] 

什么是寻找解决这些的最彻底的方法?

  1. 最小日期其中Type = 1

=> 2017年2月1日

  • 选择内容其中Type = 2和日期= (与第一类型的所有对象中最小日期= 2)
  • => AAAAAAAA

    我在阅读关于利用lambda和过滤器,但我一直无法取得任何进展。任何人都可以帮忙吗?

    +0

    你在db上还是仅仅在列表中有这些对象?如果他们在db中,你可以使用ORM进行查询,这将更容易和更有效地检索。 –

    +0

    数据库中没有它们。 :( – 90abyss

    回答

    7

    这些是基本的Python数据结构。我建议使用理解而不是mapfilter。例如:

    >>> listt = [{ 
    ...  "CustomerId": "1", 
    ...  "Date": "2017-02-02", 
    ...  "Content": "AAAAAAAA", 
    ...  "Type": 2 
    ...  }, 
    ...  { 
    ...  "CustomerId": "2", 
    ...  "Date": "2017-02-03", 
    ...  "Content": "BBBBBBBB", 
    ...  "Type": 1 
    ...  }, 
    ...  { 
    ...  "CustomerId": "3", 
    ...  "Date": "2017-02-01", 
    ...  "Content": "CCCCCCCCC", 
    ...  "Type": 1 
    ...  }, 
    ...  { 
    ...  "CustomerId": "4", 
    ...  "Date": "2017-02-12", 
    ...  "Content": "DDDDDDDDDD", 
    ...  "Type": 2 
    ...  }, ] 
    >>> min(d['Date'] for d in listt if d['Type'] == 1) 
    '2017-02-01' 
    >>> 
    

    或者,如果您第二个查询:

    >>> min_date = min(d['Date'] for d in listt if d['Type'] == 2) 
    >>> [d['Content'] for d in listt if d['Date'] == min_date] 
    ['AAAAAAAA'] 
    >>> 
    

    尽量坚持修真结构使事情变得更易读,海事组织,而不是使用lambda,虽然,也有它的地方,是而是一个风格问题。然而,列表理解在总体上更快比等效maplambda更快。但是,使用内置函数,map可以更快。

    +0

    简单,清晰,美观... –

    +0

    但是它遍历了两次我发现并不优雅的列表,通过使用枚举函数可以找到最小值和内容,只有一个列表遍历 - 参见下面 –

    +0

    @AndiKleve是的,的确,最好是简单地返回整个词典并在那里查询最后一个键 –

    1

    用于查找与类型= 1的最小日期,则可以首先筛选的类型= 1的列表,然后通过过滤列表以min功能(带有密钥作为lambda x: x['Date']找到具有最小“日期”元素)作为:

    #      performs `min` operation on `'Date'` v 
    >>> min([d for d in listt if d['Type'] ==1], key=lambda x: x['Date']) 
    {'CustomerId': '3', 'Type': 1, 'Content': 'CCCCCCCCC', 'Date': '2017-02-01'} 
    

    这是具有在列表中的最小一个Date对象dict。假设它被存储为变量my_dict。为了找到为止,做:

    my_dict['Date'] 
    

    为了找到与之相关的内容,这样做:

    my_dict['Content'] 
    

    注:对于发现的Type=2的内容,以及在d['Type'] ==2更换d['Type'] ==1min声明。

    0

    这是一个带有解释的版本。对于第一个问题:

    minval = min(elem['CustomerId'] for elem in listt if elem['Type']==1) 
    print(minval) 
    

    对于第二个版本,你可能不希望首先搜索最低,然后每个元素比较到最小,因为这将需要遍历列表的两倍。相反,最好搜索最小值并跟踪其索引。这可以通过使用enumerate函数在理解中容易地完成:

    minval, index = min((elem['CustomerId'], _) 
            for _, elem in enumerate(listt) if elem['Type']==2) 
    print(minval, listt[index]) 
    
    +0

    我将规范解释为“返回所有内容”,而不仅仅是与最小值对应的内容。在这种情况下,无论如何都需要双程。 –

    +0

    @ juanpa.arivillaga:同意 - 根据这个解释,我也会使用两遍。 –