迭代python列表并求和相等的项

时间:2022-07-24 19:28:08

Considering a endpoint on my backend, that returns the following response:

考虑到我后端的端点,它返回以下响应:

class Arc_Edges_Data(Resource):
  def get(self):
        #Connect to databse
        conn = connectDB()
        cur = conn.cursor()
        #Perform query and return JSON data
        try:
          cur.execute("select json_build_object('source', start_location, 'target', end_location, 'frequency', 1) from trips")
        except:
          print("Error executing select")
        ArcList = list (i[0] for i in cur.fetchall())
        return ArcList

The frequency here is supposed to be always of 1 for each trip. So this ArcList originates a response like this:

每次旅行的频率应始终为1。所以这个ArcList发起了这样的响应:

[
    {
        "frequency": 1, 
        "source": "c", 
        "target": "c"
    }, 
    {
        "frequency": 1, 
        "source": "a", 
        "target": "b"
    }, {
        "frequency": 1, 
        "source": "a", 
        "target": "b"
    }, ...
]

How can I iterate this response and sum the items that have the same source and target? In this case, the resulting list would have only one pair source/target with "a" and "b", but the frequency would be 2, because of the sum.

如何迭代此响应并对具有相同源和目标的项进行求和?在这种情况下,结果列表将只有一对源/目标具有“a”和“b”,但由于总和,频率将为2。

I know that for Javascript I could use something like Array.reduce, but I don't think it exists for Python.

我知道对于Javascript我可以使用像Array.reduce这样的东西,但我不认为它存在于Python中。

2 个解决方案

#1


2  

How about this?

这个怎么样?

import collections

data = [
    {
        "frequency": 1, 
        "source": "c", 
        "target": "c",
    }, 
    {
        "frequency": 1, 
        "source": "a", 
        "target": "b",
    },
    {
        "frequency": 1, 
        "source": "a", 
        "target": "b",
    },
]

counter = collections.Counter()

for datum in data:
    counter[(datum['source'], datum['target'])] += datum['frequency']

print(counter)

# Output:
# Counter({('a', 'b'): 2, ('c', 'c'): 1})

Oh, if you want to put the data back into the same format again, add this code:

哦,如果你想再次将数据恢复为相同的格式,请添加以下代码:

newdata = [{
    'source': k[0],
    'target': k[1],
    'frequency': v,
} for k, v in counter.items()]

print(newdata)

# Output:
# [{'frequency': 1, 'target': 'c', 'source': 'c'}, {'frequency': 2, 'target': 'b', 'source': 'a'}]

#2


0  

You could do this:

你可以这样做:

r = {}
for d in ArcList:
    key = (d['source'], d['target'])
    r[key] = r.setdefault(key, 0) + d['frequency']
return [{'source': k[0], 'target': k[1], 'frequency': v} for k, v in r.items()]

If you want to preserve the original ordering of the items:

如果要保留项目的原始顺序:

from collections import OrderedDict
r = OrderedDict()
# The rest of the solution is the same
...

#1


2  

How about this?

这个怎么样?

import collections

data = [
    {
        "frequency": 1, 
        "source": "c", 
        "target": "c",
    }, 
    {
        "frequency": 1, 
        "source": "a", 
        "target": "b",
    },
    {
        "frequency": 1, 
        "source": "a", 
        "target": "b",
    },
]

counter = collections.Counter()

for datum in data:
    counter[(datum['source'], datum['target'])] += datum['frequency']

print(counter)

# Output:
# Counter({('a', 'b'): 2, ('c', 'c'): 1})

Oh, if you want to put the data back into the same format again, add this code:

哦,如果你想再次将数据恢复为相同的格式,请添加以下代码:

newdata = [{
    'source': k[0],
    'target': k[1],
    'frequency': v,
} for k, v in counter.items()]

print(newdata)

# Output:
# [{'frequency': 1, 'target': 'c', 'source': 'c'}, {'frequency': 2, 'target': 'b', 'source': 'a'}]

#2


0  

You could do this:

你可以这样做:

r = {}
for d in ArcList:
    key = (d['source'], d['target'])
    r[key] = r.setdefault(key, 0) + d['frequency']
return [{'source': k[0], 'target': k[1], 'frequency': v} for k, v in r.items()]

If you want to preserve the original ordering of the items:

如果要保留项目的原始顺序:

from collections import OrderedDict
r = OrderedDict()
# The rest of the solution is the same
...