Python - 根据另一个对象列表的计数创建一个对象列表
Python - Create a list of objects based on counts of another list of objects
我有一个对象列表,我想创建另一个项目列表,但按“名称”和两个字段分组,这两个字段是特定实例类型的实例数。
我有这个:
result = [
{"Name": "Foo", "Type": "A", "RandomColumn1": "1"},
{"Name": "Bar", "Type": "B", "RandomColumn2": "2"},
{"Name": "Foo", "Type": "A", "RandomColumn3": "3"},
{"Name": "Bar", "Type": "A", "RandomColumn4": "4"},
{"Name": "Foo", "Type": "B", "RandomColumn5": "5"},
]
我正在尝试计算不同“类型”列的数量,同时丢弃任何其他列 - 在本例中为 RandomColumnX。
我要上面这样出来:
[{"Name": "Foo", "A": 2, "B": 1}, {"Name": "Bar", "A": 1, "B": 1}]
我试过这样做:
group_requests = [{
"Name": key,
"A": len([d for d in list(value) if d.get('Type') == 'A']),
"B": len([y for y in list(value) if y['Type'] == 'B']),
} for key, value in groupby(result, key=lambda x: x['Name'])]
但是,它不计算“B”列中的值,并且此键的计数始终为 0。
有人可以帮我吗?
错误一.
为了让 itertools.groupby
工作,你的输入迭代需要已经在相同的键函数上排序。
result = sorted(result, key=lambda x: x["Name"])
错误2.
返回的组即 value
本身就是一个迭代器,因此您需要保存输出以便多次迭代它。
group_requests = []
for key, value in itertools.groupby(result, key=lambda x: x["Name"]):
<b>value = list(value) # save the output</b>
temp = {
"Name": key,
"A": len([d for d in value if d.get("Type") == "A"]),
"B": len([y for y in value if y["Type"] == "B"]),
}
group_requests.append(temp)
如果有人想要没有列表理解。可以这样实现
from collections import defaultdict
result = [{"Name": "Foo", "Type": "A", "RandomColumn1": "1"},
{"Name": "Bar", "Type": "B", "RandomColumn2": "2"},
{"Name": "Foo", "Type": "A", "RandomColumn3": "3"},
{"Name": "Bar", "Type": "A", "RandomColumn4": "4"},
{"Name": "Foo", "Type": "B", "RandomColumn5": "5"}]
group_requests = []
counterA = defaultdict(int)
counterB = defaultdict(int)
names = set()
for val in result:
name = val["Name"]
type = val["Type"]
if type == "A":
counterA[name] += 1
else:
counterB[name] += 1
names.add(name)
for name in names:
group_requests.append({
"Name": name,
"A": counterA[name],
"B": counterB[name]
})
print(group_requests)
我有一个对象列表,我想创建另一个项目列表,但按“名称”和两个字段分组,这两个字段是特定实例类型的实例数。 我有这个:
result = [
{"Name": "Foo", "Type": "A", "RandomColumn1": "1"},
{"Name": "Bar", "Type": "B", "RandomColumn2": "2"},
{"Name": "Foo", "Type": "A", "RandomColumn3": "3"},
{"Name": "Bar", "Type": "A", "RandomColumn4": "4"},
{"Name": "Foo", "Type": "B", "RandomColumn5": "5"},
]
我正在尝试计算不同“类型”列的数量,同时丢弃任何其他列 - 在本例中为 RandomColumnX。
我要上面这样出来:
[{"Name": "Foo", "A": 2, "B": 1}, {"Name": "Bar", "A": 1, "B": 1}]
我试过这样做:
group_requests = [{
"Name": key,
"A": len([d for d in list(value) if d.get('Type') == 'A']),
"B": len([y for y in list(value) if y['Type'] == 'B']),
} for key, value in groupby(result, key=lambda x: x['Name'])]
但是,它不计算“B”列中的值,并且此键的计数始终为 0。
有人可以帮我吗?
错误一.
为了让 itertools.groupby
工作,你的输入迭代需要已经在相同的键函数上排序。
result = sorted(result, key=lambda x: x["Name"])
错误2.
返回的组即 value
本身就是一个迭代器,因此您需要保存输出以便多次迭代它。
group_requests = []
for key, value in itertools.groupby(result, key=lambda x: x["Name"]):
<b>value = list(value) # save the output</b>
temp = {
"Name": key,
"A": len([d for d in value if d.get("Type") == "A"]),
"B": len([y for y in value if y["Type"] == "B"]),
}
group_requests.append(temp)
如果有人想要没有列表理解。可以这样实现
from collections import defaultdict
result = [{"Name": "Foo", "Type": "A", "RandomColumn1": "1"},
{"Name": "Bar", "Type": "B", "RandomColumn2": "2"},
{"Name": "Foo", "Type": "A", "RandomColumn3": "3"},
{"Name": "Bar", "Type": "A", "RandomColumn4": "4"},
{"Name": "Foo", "Type": "B", "RandomColumn5": "5"}]
group_requests = []
counterA = defaultdict(int)
counterB = defaultdict(int)
names = set()
for val in result:
name = val["Name"]
type = val["Type"]
if type == "A":
counterA[name] += 1
else:
counterB[name] += 1
names.add(name)
for name in names:
group_requests.append({
"Name": name,
"A": counterA[name],
"B": counterB[name]
})
print(group_requests)