简体   繁体   English

python 列表 - 使用推导将现有列表列表转换为每个键具有多个值的字典

[英]python lists - convert an existing list of lists into a dict with multiple values per key using a comprehension

I have a relatively simple problem that is easily solved with setdefault , but I'm self-learning comprehensions right now and can't figure out how to do this with a comprehension.我有一个相对简单的问题,可以使用setdefault轻松解决,但我现在正在自学理解,无法弄清楚如何通过理解来做到这一点。

Let's say I have a nested list where some of the inner lists have the same keys.假设我有一个嵌套列表,其中一些内部列表具有相同的键。 This means that I should be able to generate a dict where some keys have multiple values.这意味着我应该能够生成一个字典,其中一些键具有多个值。 I keep trying to somehow append the values but every time it just returns that last single digit value or else give an error.我一直在尝试以某种方式 append 的值,但每次它只返回最后一个数字值,否则会出错。

Here is an example:这是一个例子:

>>> strlist
['hello w', 'hello', 'hello c', 'hello c c', 'dog']

>>> [[k,v] for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x]
[['hello', 0], ['hello', 1], ['hello', 2], ['hello', 3], ['w', 0], ['c', 2], ['c', 3], ['dog', 4]]

I also tried it with a list of tuples, a tuple of tuples, a set of lists, a set of tuples, etc. Still can't get it to work with a comprehension.我还尝试了一个元组列表、一个元组元组、一组列表、一组元组等。仍然无法让它与理解一起工作。

Here are a few failed attempts:以下是一些失败的尝试:

>>> dict([(k,v) for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x])
{'hello': 3, 'w': 0, 'c': 3, 'dog': 4}

>>> {k:k[v] for k,v in [[k,v] for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x]}
Traceback (most recent call last):
  File "<pyshell#285>", line 1, in <module>
    {k:k[v] for k,v in [[k,v] for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x]}
  File "<pyshell#285>", line 1, in <dictcomp>
    {k:k[v] for k,v in [[k,v] for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x]}
IndexError: string index out of range

>>> {k:{v} for k,v in [[k,v] for k in set(sum([x.split() for x in strlist],[])) for v,x in enumerate(strlist) if k in x]}
{'hello': {3}, 'w': {0}, 'c': {3}, 'dog': {4}}

The goal is to get this:目标是得到这个:

>>> {'hello': {0, 1, 2, 3], 'w': {0}, 'c': {2, 3}, 'dog': {4}}

Is this even possible with a comprehension or must I use one of the more common traditional loop methods?这甚至可以通过理解实现,还是我必须使用更常见的传统循环方法之一?

Use your method to transform strlist to list of lists and then you can use collections.defaultdict :使用您的方法将strlist转换为列表列表,然后您可以使用collections.defaultdict

from collections import defaultdict

lst = [
    ["hello", 0],
    ["hello", 1],
    ["hello", 2],
    ["hello", 3],
    ["w", 0],
    ["c", 2],
    ["c", 3],
    ["dog", 4],
]   

d = defaultdict(set)
for x, y in lst:
    d[x].add(y)
    
print(d)
# defaultdict(<class 'set'>, {'hello': {0, 1, 2, 3}, 'w': {0}, 'c': {2, 3}, 'dog': {4}})

Since, you ask for a dictionary-comprehension:因为,您要求字典理解:

d = {k: set(y for x, y in lst if x == k) for k, _ in lst}

This is a way of doing it in one line, using dict comprehension.这是一种使用 dict 理解在一行中执行此操作的方法。 However, I'm not sure if this is a best option in terms of efficiency than a more conventional for loop, using things like setdefault() and some temporal list.但是,我不确定这是否比使用setdefault()和一些临时列表等更传统的 for 循环在效率方面是最佳选择。

list_ = ['hello w', 'hello', 'hello c', 'hello c c', 'dog']
result = {
    word: {i for i, phrase in enumerate(list_) if word in phrase}
    for string in list_
    for word in string.split()
}

content of result : result内容:

{'hello': {0, 1, 2, 3}, 'w': {0}, 'c': {2, 3}, 'dog': {4}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM