【问题标题】:Filter a dictionary of lists in Python在 Python 中过滤列表字典
【发布时间】:2017-10-29 22:16:42
【问题描述】:

我有以下字典:

dict = {'Sex':['Male','Male','Female','Female','Male'],
        'Height': [100,200,150,80,90],
        'Weight': [20,60,40,30,30]}

我希望能够使用一个键上的条件来过滤该字典。例如,如果我只想保留男性:

new_dict = {'Sex':['Male','Male','Male'],
            'Height': [100,200,90],
            'Weight': [20,60,30]}

【问题讨论】:

  • 将其转换为数据库。
  • 谢谢,但在我的配置中并不理想。
  • 您想变得多灵活?另一个例子可以是height > 100吗?
  • 是的,例如。有什么简单的方法可以用代码做到这一点?

标签: python dictionary


【解决方案1】:

您可以使用dict理解并在构建值列表时检查键'Sex'的相应索引处的项目:

d = {k: [x for i, x in enumerate(v) if dct['Sex'][i]=='Male'] 
                                      for k, v in dct.items()}
print(d)
# {'Sex': ['Male', 'Male', 'Male'], 
#  'Weight': [20, 60, 30], 
#  'Height': [100, 200, 90]}

【讨论】:

    【解决方案2】:

    与其尝试跟踪索引,不如将数据结构“转置”为字典列表:

    data = [{'Sex': 'Male', 'Height': 100, 'Weight': 20},
            {'Sex': 'Male', 'Height': 200, 'Weight': 60},
            {'Sex': 'Female', 'Height': 150, 'Weight': 40},
            {'Sex': 'Female', 'Height': 80, 'Weight': 30},
            {'Sex': 'Male', 'Height': 90, 'Weight': 30}]
    
    only_males = [person for person in data if person['Sex'] == 'Male']
    only_males
    # [{'Sex': 'Male', 'Height': 100, 'Weight': 20},
    #  {'Sex': 'Male', 'Height': 200, 'Weight': 60},
    #  {'Sex': 'Male', 'Height': 90, 'Weight': 30}]
    

    【讨论】:

    • 因此,您应该展示 OP 如何在假设数据很大的情况下转置数据。你是最好的选择 IMO 只使用字典
    • 我的猜测是数据以 DeepSpace 建议的格式出现,并且 OP 对其进行了一些努力以使其具有他向我们展示的格式...
    【解决方案3】:

    使用collections.defaultdictzip()函数的解决方案:

    d = {
        'Sex':['Male','Male','Female','Female','Male'],
        'Height': [100,200,150,80,90],
        'Weight': [20,60,40,30,30]
    }
    
    result = collections.defaultdict(list)
    for s,h,w in zip(d['Sex'], d['Height'], d['Weight']):
        if s == 'Male':
            result['Sex'].append(s)
            result['Height'].append(h)
            result['Weight'].append(w)
    
    print(dict(result))
    

    输出:

    {'Sex': ['Male', 'Male', 'Male'], 'Weight': [20, 60, 30], 'Height': [100, 200, 90]}
    

    【讨论】:

      【解决方案4】:

      反正我已经写好了,我就把它放在这里。它会根据您的字典在内存中创建一个数据库,然后您可以查询该数据库(您可能会注意到很灵活)以获得您想要的结果。

      dict_ = {'Sex': ['Male', 'Male', 'Female', 'Female', 'Male'],
              'Height': [100, 200, 150, 80, 90],
              'Weight': [20, 60, 40, 30, 30]}
      
      import sqlite3
      
      conn = sqlite3.connect(':memory:')
      curs = conn.cursor()
      column_headers = [x for x in dict_]  # the keys are the headers
      column_types = ('' for x in dict_)
      header_creation = ', '.join([' '.join(x) for x in zip(column_headers, column_types)])
      curs.execute("CREATE TABLE temp ({})".format(header_creation))
      bindings = ','.join('?' * (header_creation.count(',') + 1))
      result_insertion = "INSERT INTO temp ({}) VALUES ({})".format(', '.join(column_headers), bindings)
      for i, item in enumerate(dict_[column_headers[0]]):
          values = [item]
          for j in column_headers[1:]:
              values.append(dict_[j][i])
          curs.execute(result_insertion, values)
      conn.commit()
      
      condition = 'weight >= 40'
      
      out = curs.execute('SELECT * FROM temp{}'.format(' WHERE {}'.format(condition) if condition else ';')).fetchall()
      dict_out = {}
      for i, k in enumerate(column_headers):
          dict_out[k] = [x[i] for x in out]
      print(dict_out)  # {'Sex': ['Male', 'Female'], 'Weight': [60, 40], 'Height': [200, 150]}
      

      【讨论】:

        【解决方案5】:

        您可以使用itertools.compress 和字典理解:

        >>> import itertools
        
        >>> dct = {'Sex':    ['Male', 'Male', 'Female', 'Female', 'Male'],
        ...        'Height': [100, 200, 150, 80, 90],
        ...        'Weight': [20, 60, 40, 30, 30]}
        
        >>> mask = [item == 'Male' for item in dct['Sex']]
        
        >>> new_dict = {key: list(itertools.compress(dct[key], mask)) for key in dct}
        >>> new_dict
        {'Height': [100, 200, 90],
         'Sex': ['Male', 'Male', 'Male'],
         'Weight': [20, 60, 30]}
        

        【讨论】:

          【解决方案6】:

          您可以使用 pandas DataFrame(install 包优先)

          >>> data = pandas.DataFrame(
             {'Sex':['Male','Male','Female','Female','Male'],
              'Height': [100,200,150,80,90],
              'Weight': [20,60,40,30,30]}
          )
          
          >>> data[data['Sex'] == 'Male']
             Height   Sex  Weight
          0     100  Male      20
          1     200  Male      60
          4      90  Male      30
          

          这将更像一个数据库,您可以毫不费力地过滤更多的东西。

          【讨论】:

            【解决方案7】:

            就我个人而言,我会改用对象列表,以便在同一个对象中具有相关属性,这样:

            people = [{"Sex": "Male", "Height": 100, "Weight": 20}, {...}, ...]
            

            我会以这种方式转换为列表(假设您的字典中的列表都具有相同的大小):

            list = []
            for i in range(len(dict["Sex"])):
                list.append({k: v[i] for k, v in dict.iteritems()})
            

            如果您使用的是 python 3.x,请使用 d.items()

            然后就可以很方便的按key值过滤列表了,更多详情here

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-03-23
              • 1970-01-01
              • 2021-11-21
              • 2022-01-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多