如果条目匹配,则减少列表列表
Reduce list of lists if entries match
我在 python 中有一个列表,看起来像
[['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
我想根据每个列表中的前 2 个条目减少列表,得到
[['boy','121',is a male child, is male, is a child'],['girl','122','is a female child','is a child']]
有没有一种方法可以在不创建虚拟列表的情况下高效地执行此操作?
作为此类任务的更 pythonic 方式,您可以使用字典:
>>> li=[['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
>>>
>>> d={}
>>>
>>> for i,j,k in li:
... d.setdefault((i,j),[]).append(k)
...
>>> d
{('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']}
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
如果你想将元素放在 1 个容器中,你可以遍历这些项目并将值转换为 tuple
然后使用键对其进行广告:
>>> [i+tuple(j) for i,j in d.items()]
[('boy', '121', 'is a male child', 'is male', 'is a child'), ('girl', '122', 'is a female child', 'is a child')]
正如@jonrsharpe 所说,作为一种更优雅的方式,您还可以使用 collections.defaultdict
:
>>> from collections import defaultdict
>>>
>>> d=defaultdict(list)
>>> for i,j,k in li:
... d[i,j].append(k)
...
>>> d
defaultdict(<type 'list'>, {('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']})
您可以为此使用 itertools.groupby
:
>>> l = [['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
>>> import itertools
>>> [k+[m[2] for m in v] for k,v in itertools.groupby(l,key = lambda x:x[:2])]
[['boy', '121', 'is a male child', 'is male', 'is a child'], ['girl', '122', 'is a female child', 'is a child']]
来自文档
itertools.groupby(iterable[, key])
Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each
element.
我在 python 中有一个列表,看起来像
[['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
我想根据每个列表中的前 2 个条目减少列表,得到
[['boy','121',is a male child, is male, is a child'],['girl','122','is a female child','is a child']]
有没有一种方法可以在不创建虚拟列表的情况下高效地执行此操作?
作为此类任务的更 pythonic 方式,您可以使用字典:
>>> li=[['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
>>>
>>> d={}
>>>
>>> for i,j,k in li:
... d.setdefault((i,j),[]).append(k)
...
>>> d
{('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']}
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
如果你想将元素放在 1 个容器中,你可以遍历这些项目并将值转换为 tuple
然后使用键对其进行广告:
>>> [i+tuple(j) for i,j in d.items()]
[('boy', '121', 'is a male child', 'is male', 'is a child'), ('girl', '122', 'is a female child', 'is a child')]
正如@jonrsharpe 所说,作为一种更优雅的方式,您还可以使用 collections.defaultdict
:
>>> from collections import defaultdict
>>>
>>> d=defaultdict(list)
>>> for i,j,k in li:
... d[i,j].append(k)
...
>>> d
defaultdict(<type 'list'>, {('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']})
您可以为此使用 itertools.groupby
:
>>> l = [['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
>>> import itertools
>>> [k+[m[2] for m in v] for k,v in itertools.groupby(l,key = lambda x:x[:2])]
[['boy', '121', 'is a male child', 'is male', 'is a child'], ['girl', '122', 'is a female child', 'is a child']]
来自文档
itertools.groupby(iterable[, key])
Make an iterator that returns consecutive keys and groups from the iterable. The key is a function computing a key value for each element.