Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建列表字典的一行程序_Python - Fatal编程技术网

Python 创建列表字典的一行程序

Python 创建列表字典的一行程序,python,Python,如何做这个列表/听写理解 转动这个[(“a”,1),(“b”,2),(“a”,3)] 进入这个 { "a": [1, 3], "b": [2] } 我知道如何在for循环中完成这项工作,我可以只用一行来完成这项工作吗?一个简单的方法是使用一个简单的列表: from collections import defaultdict lst = [("a", 1), ("b", 2), ("a", 3)] items = defaultdict(list) for k, v in lst:

如何做这个列表/听写理解 转动这个
[(“a”,1),(“b”,2),(“a”,3)]

进入这个

{
  "a": [1, 3],
  "b": [2]
}

我知道如何在for循环中完成这项工作,我可以只用一行来完成这项工作吗?

一个简单的方法是使用一个简单的列表:

from collections import defaultdict

lst = [("a", 1), ("b", 2), ("a", 3)]

items = defaultdict(list)
for k, v in lst:
    items[k].append(v)

print(items)
这就产生了:

defaultdict(<class 'list'>, {'a': [1, 3], 'b': [2]})
也可以更清晰地写为:

{k: [x[1] for x in g] for k, g in groupby(sorted(lst, key=itemgetter(0)), key=itemgetter(0))}

由于排序的原因,上述解决方案具有
O(NlogN)
复杂性,如果您想将类似项目分组在一起,这是一项要求。这比第一个
defaultdict
解决方案效率低,它是
O(N)
,因为您只需要迭代列表一次。第一种解决方案更可取,因为它更易于阅读、高效和可维护

就个人而言,我认为在这里使用循环是一个简单的选项,但是为了演示,您可以在这里定义一个自定义类,该类继承自
集合

import collections

class AutoListDict(collections.MutableMapping):

  def __init__(self, values=()):            
      self.inner = collections.defaultdict(list)
      for k, v in values:
          self[k].append(v)

  def __setitem__(self, k, v): self.inner[k] = v
  def __getitem__(self, k):return self.inner[k]
  def __delitem__(self, k_): del self.inner[k]
  def __iter__(self): return iter(self.inner)
  def __len__(self): return len(self.inner)
  def __repr__(self): return str(dict(self.inner))
这将根据您的输入值初始化一个
defaultdict
,因此它不会覆盖附加到它的键。实际上,您只需在元组数组上调用类构造函数:

>>> arr = [('a', 1), ('b', 2), ('a', 3)]
>>> AutoListDict(arr)
{'a': [1, 3], 'b': [2]}
或者,如果您想要更类似于词典理解的内容:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> lst = [("a", 1), ("b", 2), ("a", 3)]
>>> {k: list(map(itemgetter(1), g)) for k, g in groupby(sorted(lst, key=itemgetter(0)), key=itemgetter(0))}
{'a': [1, 3], 'b': [2]}
>>> dct = AutoListDict((k, v) for k, v in arr)
>>> dct
{'a': [1, 3], 'b': [2]}

在这里使用一个简单的
defaultdict(list)
和一个循环没有什么错。它速度快,可读性好。你认为单行线比for循环更容易维护吗?