Python 如何在两个列表的循环中根据键求和

1 投票
6 回答
110 浏览
提问于 2025-04-14 18:30

我有这两个列表:

list1 = [
    {'user_id': 1, 'server_id': '10', 'amount': 100},
    {'user_id': 2, 'server_id': None, 'amount': 10000},
    {'user_id': 3, 'server_id': '10', 'amount': 200},
    {'user_id': 1, 'server_id': '10', 'amount': 200},
    {'user_id': 2, 'server_id': '10', 'amount': 110},
    {'user_id': 2, 'server_id': None, 'amount': 40000},
    {'user_id': 3, 'server_id': '10', 'amount': 100},
    {'user_id': 3, 'server_id': None, 'amount': 12500},
    {'user_id': 3, 'server_id': '10', 'amount': 100},
    {'user_id': 1, 'server_id': None, 'amount': 22500},
]

list2 = [
    {'id': 1},
    {'id': 4},
    {'id': 18},
    {'id': 3},
    {'id': 2},
]

逻辑是这样的:

if list1['server_id'] == None, it means the user added to the credits. if list1['server_id'] != None, then the user spent money.

if list1['user_id'] == list2['id'], then check if list1['server_id'] == None, sum all of their list1['amount'] and save to a variable called `add_funds`.
if list1['user_id'] == list2['id'], then check if list1['server_id'] != None, sum all of their list1['amount'] and save to a variable called `spent`.

finally, for each user, save a variable called `final_balance = add_funds - spent`. then print `user_id X current balance final_balance.`

这是我的代码,但我知道它不对:

tmp = []
for l2 in list2:
    for l1 in list1:
        spent = 0
        add_fund = 0
        if l1['user_id'] == l2['id'] and l1['user_id'] not in tmp:
            tmp.append(l1['user_id'])
            if l1['server_id'] == None:
                add_fund += l1['amount']
            elif l1['server_id'] != None:
                spent += l1['amount']
        final_balance = add_fund - spent
        if final_balance > 0:
            print(f"User{l1['user_id']} spent {format(spent, ',d').replace(',',',')}, add_funds {format(add_fund, ',d').replace(',',',')}, final_balance {format(final_balance, ',d').replace(',',',')}")

这是我现在的输出:

User4 spent 0, add_funds 85,700, final_balance 85,700
User4 spent 0, add_funds 10,000, final_balance 10,000

我知道这段代码里有这些问题:

  1. 我在每次循环时都把花费(spent)设为0,如果接下来的两个ID不匹配,它又会变回0。最后一句话对于add_fund也是正确的。

我想要达到的正确输出应该是:

User1 spent 300, add_funds 22,500, final_balance 22,200
User2 spent 110, add_funds 50,000, final_balance 49,890
User3 spent 400, add_funds 12,500, final_balance 12,100

6 个回答

1

你也可以这样做,使用 dict 来在循环中存储数据。

list1 = [
    {'user_id': 1, 'server_id': '10', 'amount': 100},
    {'user_id': 2, 'server_id': None, 'amount': 10000},
    {'user_id': 3, 'server_id': '10', 'amount': 200},
    {'user_id': 1, 'server_id': '10', 'amount': 200},
    {'user_id': 2, 'server_id': '10', 'amount': 110},
    {'user_id': 2, 'server_id': None, 'amount': 40000},
    {'user_id': 3, 'server_id': '10', 'amount': 100},
    {'user_id': 3, 'server_id': None, 'amount': 12500},
    {'user_id': 3, 'server_id': '10', 'amount': 100},
    {'user_id': 1, 'server_id': None, 'amount': 22500},
]


result = {
            "user_id": None,
            
                "added": 0,
                "spent": 0,
                "total":0
            
}
from copy import copy

sol = {}

for user_data in list1:
    user_id = user_data['user_id']
    if user_id not in sol:
        sol[user_id] = copy(result)
        sol[user_id]['user_id'] = user_id
    if user_data['server_id'] == None:
        sol[user_id]["added"] += user_data['amount']
    elif user_data['server_id'] != None:
        sol[user_id]['spent'] += user_data['amount']
    sol[user_id]['total'] = sol[user_id]['added'] - sol[user_id]['spent']


print(sol)

输出结果

{
    1: {'user_id': 1, 'added': 22500, 'spent': 300, 'total': 22200},
    2: {'user_id': 2, 'added': 50000, 'spent': 110, 'total': 49890},
    3: {'user_id': 3, 'added': 12500, 'spent': 400, 'total': 12100}
}
2

也许这个方法会更可靠,但理解起来有点难。简单来说,它使用了 filter 函数,只获取 list1 中的一部分记录(我筛选出当前用户的交易记录,并且只筛选出增加或减少资金的交易)。接着,它用 map 函数把每一笔交易的数据(比如 {'user_id': 1, 'server_id': None, 'amount': 22500})转换成仅仅是金额部分,也就是 22500。最后,这些金额会被 sum 函数加起来。

def format_money(num):
    return format(num, ',d').replace(',',',') 

for user in list2:
    uid = user['id']
    
    transactions = list(filter(lambda t: t.get('user_id') == uid, list1))
    total_funded = sum(
        map(lambda t: t.get('amount'), 
        filter(lambda t: t.get('server_id') is None, transactions)))
    total_spent = sum(
        map(lambda t: t.get('amount'), 
        filter(lambda t: t.get('server_id') is not None, transactions)))
    final_balance = total_funded - total_spent
    if final_balance > 0:
       print(f"User{uid} spent {format_money(total_spent)}, add_funds {format_money(total_funded)}, final_balance {format_money(final_balance)}")
2

为了正确计算每个用户的资金添加、支出和最终余额,你可以按照以下步骤进行:

  1. 遍历包含用户ID的列表。
  2. 对于每个用户,从包含交易详情的列表中筛选出他们的交易记录。
  3. 对那些server_id为None的交易金额进行求和,以计算添加的资金(add_funds)。
  4. 对那些server_id不为None的交易金额进行求和,以计算支出(spent)。
  5. 每个用户的最终余额(final_balance)计算为添加的资金减去支出。然后存储并打印结果。
list1 = [
    # Your transactions list
]

list2 = [
    # Your user IDs list
]

user_balances = {}

for user in list2:
    user_id = user['id']
    add_funds = sum(item['amount'] for item in list1 if item['user_id'] == user_id and item['server_id'] is None)
    spent = sum(item['amount'] for item in list1 if item['user_id'] == user_id and item['server_id'] is not None)
    final_balance = add_funds - spent
    
    if add_funds or spent:
        user_balances[user_id] = {'spent': spent, 'add_funds': add_funds, 'final_balance': final_balance}

for user_id, balances in user_balances.items():
    print(f"User {user_id} spent {balances['spent']}, added funds {balances['add_funds']}, final balance {balances['final_balance']}")

撰写回答