【问题标题】:Creating dictionary from list of lists and obtain the maximum keys in python从列表列表创建字典并获取python中的最大键
【发布时间】:2017-07-27 22:19:03
【问题描述】:

我正在尝试从列表列表中创建字典。我创建了一个与我正在研究的类似内容的示例,如下所示:

lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
lst2 = [[1,8,2],[4,3,6],[7,9,0]]

我试过这样的

mydict = [dict(zip(keys,values)) for keys in lst1 for values in lst2]

print (mydict) 
# Prints like this below 
#[{'a': 1, 'b': 8, 'c': 2}, {'a': 4, 'b': 3, 'c': 6}, {'a': 7, 'b': 9, 'c': 0}, {'d': 1, 'e': 8, 'a': 2}, {'d': 4, 'e': 3, 'a': 6}, {'d': 7, 'e': 9, 'a': 0}, {'g': 1, 'b': 8, 'i': 2}, {'g': 4, 'b': 3, 'i': 6}, {'g': 7, 'b': 9, 'i': 0}]

我可以看到我正在做的错误是在lst1 循环内迭代lst2,因此键和值被多次分配。但我需要这样的输出

{{'a': 1, 'b': 8, 'c': 2}, {'d': 4, 'e': 3, 'a': 6}, {'g': 7, 'b': 9, 'i': 0}}

我想保留列表的结构并为字典创建一个键和值,通过它我可以获得字典的最大键。 所以我的最终目标是得到这个

"""
In the mydict 
{{'a': 1, 'b': 8, 'c': 2}, 
 {'d': 4, 'e': 3, 'a': 6}, 
 {'g': 7, 'b': 9, 'i': 0}}

the key 'b' has max_value of 8,
the key 'a' has max_value of 6,
the key 'b' has max_value of 9.

#the output i need is  [['b'],['a'],['b']]
"""

已编辑:

感谢大家的回答,迭代一旦找到最大值就停止,如何获取所有具有最大值的键。例如:

lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
lst2 = [[1,8,2],[4,3,6],[7,9,9]]

需要输出为

[['b'], ['a'], ['b','i']]

【问题讨论】:

  • 为什么max_mydict 是一个列表列表
  • 你为什么要创建字典来查找max_mydict
  • 抱歉打错了,我想要 max_mydict 看起来像这样。现在更正了

标签: python list dictionary


【解决方案1】:

要生成您可以使用的字典

>>> [dict(z) for z in map(zip, lst1, lst2)]
[{'a': 1, 'b': 8, 'c': 2}, {'d': 4, 'e': 3, 'a': 6}, {'g': 7, 'b': 9, 'i': 0}]

不过,如果您只需要对应于最大值的字母,则不必创建 dict 对象:

>>> [max(z)[1] for z in map(zip, lst2, lst1)]
['b', 'a', 'b']

【讨论】:

    【解决方案2】:

    您可以使用zip 获得max_mydict 而无需中间字典。

    这基本上是在list2中的每个子列表中找到max item的索引,然后从list1中获取对应的值。

    >>> [a[max(range(len(b)), key=b.__getitem__)] for a, b in zip(lst1, lst2)]
    ['b', 'a', 'b']
    

    分两步:

    >>> indices = (max(range(len(x)), key=x.__getitem__) for x in lst2)
    >>> [x[next(indices)] for x in lst1]
    ['b', 'a', 'b']
    

    【讨论】:

      【解决方案3】:

      您的更新意味着您需要使用循环来提高效率,例如:

      In []:
      r = []
      for xs, ys in zip(lst1, lst2):
          m = max(ys)
          r.append([x for x, y in zip(xs, ys) if y == m])
      r
      
      Out[]:
      [['b'], ['a'], ['b', 'i']]
      

      这是低效的(多次调用max())理解版本:

      In []:
      [[x for x, y in zip(xs, ys) if y == max(ys)] for xs, ys in zip(lst1, lst2)]
      
      Out[]:
      [['b'], ['a'], ['b', 'i']]
      

      如果您真的想创建一个dict,那么我会反转关系并将数字作为键,例如:

      In []:
      r = []
      for xs, ys in zip(lst1, lst2):
          d = {}
          for x, y in zip(xs, ys):
              d.setdefault(y, []).append(x)
          r.append(d)
      r
      
      Out[]:
      [{1: ['a'], 2: ['c'], 8: ['b']}, {3: ['e'], 4: ['d'], 6: ['a']}, {7: ['g'], 9: ['b', 'i']}]
      

      然后得到最大值:

      In []:
      [d[max(d)] for d in r]
      
      Out[]:
      [['b'], ['a'], ['b', 'i']]
      

      【讨论】:

      • 非常感谢您的回答,效果很好。第一个代码的第五行末尾缺少括号,显示错误。
      【解决方案4】:

      您可以使用以下列表推导。 压缩第二次从第一个 zip 开始成对列出并在这些列表上调用 dict

      l = [dict(zip(x, y)) for x, y in zip(lst1, lst2)]
      print l
      # [{'a': 1, 'c': 2, 'b': 8}, {'a': 6, 'e': 3, 'd': 4}, {'i': 0, 'b': 9, 'g': 7}]
      

      您可以使用以下方法生成最大值:

      print  [[max(d, key=d.get)] for d in l]
      # [['b'], ['a'], ['b']]
      

      【讨论】:

        【解决方案5】:

        你可以试试这个:

        lst1 = [['a','b','c'],['d','e','a'],['g','b','i']]
        lst2 = [[1,8,2],[4,3,6],[7,9,0]]
        
        final = [{c:d for c, d in zip(a, b)} for a, b in zip(lst1, lst2))]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多