Python 如何在两个列表的循环中根据键求和
我有这两个列表:
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
我知道这段代码里有这些问题:
- 我在每次循环时都把花费(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
为了正确计算每个用户的资金添加、支出和最终余额,你可以按照以下步骤进行:
- 遍历包含用户ID的列表。
- 对于每个用户,从包含交易详情的列表中筛选出他们的交易记录。
- 对那些server_id为None的交易金额进行求和,以计算添加的资金(add_funds)。
- 对那些server_id不为None的交易金额进行求和,以计算支出(spent)。
- 每个用户的最终余额(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']}")