我正在使用Python 2.7,我正在尝试重复删除列表列表并合并重复项的值。
现在我有:
original_list = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
我希望匹配每个嵌套列表的第一个元素,然后添加第二个元素的值。我想最终得到这个(最终列表的顺序无关紧要):
ideal_output = [['a', 2], ['b', 7], ['c', 2]]
到目前为止,我有一些代码会根据每个嵌套列表的第一个元素找到重复值:
for item in original_list:
matches = -1
for x in original_list:
if (item[0] == x[0]):
matches += 1
if matches >= 1:
if item[0] not in duplicates_list:
duplicates_list.append(item[0])
从这里我需要搜索original_list中的所有duplicates_list项并添加值,但我不确定最好的方法是什么。
答案 0 :(得分:30)
很多好的答案,但他们都使用了比我更多的代码,所以这是我的看法,因为它值得:
totals = {}
for k,v in original_list:
totals[k] = totals.get(k,0) + v
# totals = {'a': 2, 'c': 2, 'b': 7}
一旦你有了这样的词典,从任何这些答案中,你可以使用items
来获取元组列表:
totals.items()
# => [('a', 2), ('c', 2), ('b', 7)]
并在元组中映射list
以获取列表列表:
map(list, totals.items())
# => [['a', 2], ['c', 2], ['b', 7]]
然后按顺序排序:
sorted(map(list, totals.items()))
# => [['a', 2], ['b', 7], ['c', 2]]
答案 1 :(得分:14)
>>> from collections import Counter
>>> lst = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
>>> c = Counter(x for x, c in lst for _ in xrange(c))
Counter({'b': 7, 'a': 2, 'c': 2})
>>> map(list, c.iteritems())
[['a', 2], ['c', 2], ['b', 7]]
或者,不重复每个项目(a, b)
b次(@hcwhsa):
>>> from collections import Counter
>>> lst = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
>>> c = sum((Counter(**{k:v}) for k, v in lst), Counter())
Counter({'b': 7, 'a': 2, 'c': 2})
>>> map(list, c.iteritems())
[['a', 2], ['c', 2], ['b', 7]]
答案 2 :(得分:13)
使用collections.Counter
:
from collections import Counter
original_list = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
result = Counter()
for k, v in original_list:
result.update({k:v})
map(list, result.items())
# [['a', 2], ['c', 2], ['b', 7]]
所以,很多答案,观点和赞成。我甚至从无到有赢得了我的第一个Nice answer
(在过去的两天里,我做了很多值得更多研究和努力的答案)。鉴于此,我决定使用从头开始编写的simple script来至少完成一些研究和测试解决方案的性能。为了大小,不要直接在代码中包含代码。
每个函数都以它的作者命名,很容易找到问题。 thefourtheye
的解决方案现在等于Mark Reed中的一个,并以原始形式进行评估,基于itertools.groupby
解决方案的第2个状态进行评估。
每次测试几次(样本),每个样本依次调用几次函数迭代。我评估了样品时间的最小值,最大值和标准偏差。
我们开始,进行10次探测测试。
testing: thefourtheye, kroolik2, void, kroolik, alko, reed, visser
10 samples
10 iterations each
author min avg max stddev
reed 0.00000 0.00000 0.00000 0.00000
visser 0.00000 0.00150 0.01500 0.00450
thefourtheye 0.00000 0.00160 0.01600 0.00480
thefourtheye2 0.00000 0.00310 0.01600 0.00620
alko 0.00000 0.00630 0.01600 0.00772
void 0.01500 0.01540 0.01600 0.00049
kroolik2 0.04700 0.06430 0.07800 0.00831
kroolik 0.32800 0.34380 0.37500 0.01716
查看底部两行:此时kroolik解决方案被取消资格,因为任何合理数量的样本*迭代将执行数小时。这是最后的测试。我手动添加了一些upvotes到ouptut:
testing: thefourtheye, kroolik2, void, kroolik, alko, reed, visser
100 samples
1000 iterations each
author upvotes min avg max stddev
reed [20] 0.06200 0.08174 0.15600 0.01841
thefourtheye [5] 0.06200 0.09971 0.20300 0.01911
visser [6] 0.10900 0.12392 0.23500 0.02263
thefourtheye2 0.25000 0.29674 0.89000 0.07183
alko [11] 0.56200 0.62309 1.04700 0.08438
void [3] 1.50000 1.65480 2.39100 0.18721
kroolik [14] [DSQ]
答案 3 :(得分:10)
如果订单无关紧要,您可以使用此
original_list = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
myDict = {}
for first, second in original_list:
myDict[first] = myDict.get(first, 0) + second
result = [[key, value] for key, value in myDict.items()]
print result
或者你可以使用groupby并且代码变成一个单一的
original_list = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
from itertools import groupby
print [[key, sum(item[1] for item in list(group))]
for key, group in groupby(sorted(original_list), lambda x:x[0])]
<强>输出强>
[['a', 2], ['b', 7], ['c', 2]]
答案 4 :(得分:5)
您可以使用collections.defaultdict
:
original_list = [['a', 1], ['b', 1], ['a', 1], ['b', 1], ['b', 2], ['c', 2], ['b', 3]]
import collections
data = collections.defaultdict(list)
for item in original_list:
data[item[0]].append(item[1])
output = {key: sum(values) for key, values in data.items()}
print output
# gives: {'a': 2, 'c': 2, 'b': 7}
答案 5 :(得分:5)
我知道这很难看,但我试着用1个班轮实现它很有趣:
map(list, set(([(x[0], sum([i[1] for i in original_list if i[0]==x[0]])) for x in original_list])))
输出:
[['a', 2], ['b', 7], ['c', 2]]
答案 6 :(得分:2)
也许你也可以试试这个,
>>> x = [[1,1],[2,2],[1,1],[2,2],[3,3],[4,4],[4,4]]
>>> z = []
>>> for i in x:
>>> if i not in z:
>>> z.append(i)
>>>
>>> z
[[1, 1], [2, 2], [3, 3], [4, 4]]