如何比较列表中元组内的字符串?

3
我有一个元组列表[(amount, name)]
[(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]

我正在尝试通过它们的名称进行比较,如果有一个元组具有相同的名称,我想将金额加在一起。输出将进入另一个具有相同结构 [(amount,name)] 的列表中。我已经成功提取了名称部分,使用以下代码:
for i in range(0, len(spendList)):
    print(spendList[i][1])

输出结果:
Charlie
Ben
Charlie

我该如何将这些名称进行比较?


不要打印名称,只需访问第二个元素(spendList[i][2]),将其添加到另一个外部变量中,删除元素spendList[i]并添加一个新元素,其金额为外部变量的值。 - GalAbra
4个回答

3
text = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]
dictionary = {}
for val in text:
    amount, name = val
    if name in dictionary:
        dictionary[name] += amount
    else:
        dictionary[name] = amount
print(*dictionary.items(),sep="\n")
>>('Charlie', 427.93)
  ('Ben', 153.57)

我可以问一下在print(*dictionary.items(),sep="\n")中的*是什么意思吗? - Charlie
@Charlie解开列表的值。例:a = [1,2,3,4,5] print(*a,sep="\n")这个例子会将所有的值以新行打印出来。 - Veera Balla Deva

3

一种处理此类操作的方式是使用 dict.setdefault(),例如:

代码:

data = [(214.05, 'Charlie'), (153.57, 'Ben'), (213.88, 'Charlie')]
summed = {}
for amount, name in data:
    summed.setdefault(name, []).append(amount)
summed = [(sum(amounts), name) for name, amounts in summed.items()]
print(summed)

这是如何工作的?

  1. Start by defining a dict object to accumulate the amounts for each name.

     summed = {}
    
  2. Step through every pair of amounts and names:

     for amount, name in data:
    
  3. Using the dict property that things that hash the same will end up in the same slot in dict, and the dict method: setdefault() to make sure that the dict has an empty list available for every name we come across, create a list of amounts for each name:

     summed.setdefault(name, []).append(amount)
    

    This creates a dict of lists like:

     {'Charlie': [214.05, 213.88], 'Ben': [153.57]}
    
  4. Finally using a comprehension we can sum() up all of the items with the same name.

     summed = [(sum(amounts), name) for name, amounts in summed.items()]
    

结果:

[(427.93, 'Charlie'), (153.57, 'Ben')]

能否请您简单易懂地解释一下这段 Python 代码 for amount, name in data: summed.setdefault(name, []).append(amount) summed = {name: sum(amounts) for name, amounts in summed.items()}。我是 Python 的新手。@Stephen Rauch - Charlie
当然,我会扩展。 - Stephen Rauch
如果名字在列表中,例如[(214.05, ['Charlie','Tom']), (153.57, ['Ben','Harry']), (213.88, ['Charlie','Ben'])],该怎么办? - rmb

2

首先对列表进行排序,然后使用 itertools.groupby 函数和一个小的 lambda 函数:

from itertools import groupby

lst = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]
lst = sorted(lst, key=lambda x: x[1])

for k,v in groupby(lst, key = lambda x: x[1]):
    amount = sum(x[0] for x in v)
    print("Name: {}, Amount: {}".format(k, amount))

产生的是
Name: Ben, Amount: 153.57
Name: Charlie, Amount: 427.93

或者,使用字典推导式更简短:
summary = {name: amount 
            for name, v in groupby(lst, key = lambda x: x[1])
            for amount in [sum(x[0] for x in v)]}

print(summary)
# {'Charlie': 427.93, 'Ben': 153.57}

2
你可以使用collections.defaultdict按名称分组金额,然后在最后求和。
from collections import defaultdict

data = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]

d = defaultdict(list)
for amount, name in data:
    d[name].append(amount)

print([(_, sum(v)) for _, v in d.items()])
# [('Charlie', 427.93), ('Ben', 153.57)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接