0

我发现自己经常重复以下代码(或类似代码):

users = {}
for d in data:
    if d['user'] in users.keys():
        users[d['user']].append(d)
    else:
        users[d['user']] = [d]

在这里,数据是一个字典列表,我想将列表拆分为较小的列表,映射到它们的 d["user"] 值作为字典中的键。

我想要一种在一行中执行此操作的方法,因为这些多行让我烦恼。

但是,我能想到的唯一方法是将我的 O(N) 算法(上图)更改为 O(N^2) 算法,例如:

users = {d["user"]: [d for d in data if d["user"] == u] for d in data}

显然,这种低效率是不可接受的……

4

3 回答 3

1

您可以使用这种语法进行测试

[3*n+1 if n%2==1 else n//2 for n in range(100)]

最适合您的需求,尤其是处理理解列表等。出于您的目的,这应该这样做:

users = {users[d['user']].append(d) if d['user'] in users else users[d['user']] = [d] for d in data}
于 2020-12-14T15:50:41.220 回答
0

这与您在原始评论中发布的内容或多或少相同,但更简洁:

# set up sample data
from random import randint, choice
names = ["Alice", "Bob", "Charlie"]
data = [{"user": choice(names), "value": randint(1, 10)} for _ in range(10)]

# convert data to dict of columns
users = {}
for d in data:
    users.setdefault(d["user"], []).append(d)

如果您的数据已经排序,您可以执行以下操作

from operator import itemgetter
from itertools import groupby

# assume sorted data
data = sorted(data, key=itemgetter("user"))

{k: list(g) for k, g in itertools.groupby(data, key=itemgetter("user"))}
于 2020-12-14T16:08:25.773 回答
0

你可以把它变成一个怪物单线,像这样:

users = { u:v[u] for v in [dict()] for d in data for u in [d['user']] if not v.setdefault(u,[]).append(d) }

或者将其减少为两行,如下所示:

users = dict()
for d in data: users.setdefault(d['user'],[]).append(d)

两者都将在 O(N) 时间内运行(但我个人更喜欢第二个)

您可以做的另一件事是创建一个函数并使用它来代替:

def dataToDict(data,key):
    result = dict()
    for d in data: result.setdefault(d[key],[]).append(d)
    return result

users = dataToDict(data,"user")
于 2020-12-15T17:07:12.503 回答