我有一个嵌套列表,该如何将相同的元素加上其数字删除。
我的清单包含什么:
lis = [['apple', 32], ['Blue shirt', 323], ['Blue shirt', 320]]
我希望将此'Blue Shirt'
合并,以实现此目的:
lis = [['apple', 32], ['Blue shirt', 643]]
到目前为止我已经尝试过的
lis = [['apple',32],['Blue shirt',323],['Blue shirt',320]]
l = -1
new = 0
n = []
for i in lis:
l+=1
if lis[l][0] in i:
count = lis[l].count('Blue shirt')
if count > 1:
new += lis[l][1]
n.append(new)
name = lis[l][0]
n.append(name)
lis.pop(l)
print(n)
我的方法是计算名称的出现次数(如果超过2个),然后使用该名称和更新的价格创建一个新列表,并将其放在上一个列表的位置,但这还不够简单。
我正在尝试使用count函数,但是它似乎无法在嵌套列表上有效地工作。希望有最简单的选择来解决此问题,而无需使用某些外部函数(导入)。
答案 0 :(得分:3)
仅使用基本Python:
grouped = dict.fromkeys((x[0] for x in lis), 0) # count dict with unique lis names
for el in lis:
grouped[el[0]] += el[1] # sum values per name
[[k,v] for k, v in grouped.items()] # convert back to list
#[['apple', 32], ['Blue shirt', 643]]
不确定“外部函数”是否意味着没有其他导入-但是如果可以使用Pandas,请使用groupby
和sum
:
import pandas as pd
pd.DataFrame(lis).groupby(0, as_index=False).sum().values
array([['Blue shirt', 643],
['apple', 32]], dtype=object)
答案 1 :(得分:2)
list.count('Blue shirt')
计算列表中字符串'Blue shirt'
出现的次数。这只是一次,对您的需求而言不是有用的数字。
您想将字符串放入字典中,以便无需进行全面扫描即可跟踪数字:
counts = {}
for name, count in lis:
counts[name] = counts.get(name, 0) + count
现在您有了一个包含所有数字之和的映射;将其转换为列表列表:
lis = [[name, count] for name, count in counts.items()]
这不一定与输入列表中的元素保持相同的顺序。如果需要,您必须遍历原始列表,查看名称字符串是否仍然存在,如果存在,则将名称和计数从映射添加到新列表,然后从映射中删除名称:>
ordered_lis = []
for name, __ in lis:
if name in counts:
ordered_lis.append([name, counts.pop(name)])
但是,在Python 3.6及更高版本中,词典会记住键的插入顺序,这意味着counts.items()
上的循环会再次以原始的先见顺序为您提供字符串。
演示,使用Python 3.6:
>>> lis = [['apple', 32], ['Blue shirt', 323], ['Blue shirt', 320]]
>>> counts = {}
>>> for name, count in lis:
... counts[name] = counts.get(name, 0) + count
...
>>> [[name, count] for name, count in counts.items()]
[['apple', 32], ['Blue shirt', 643]]
如果您可以使用标准库,则还可以使用collections.defaultdict()
对象来避免使用counts.get(name, 0)
(在循环外使用counts = defaultdict(int)
和{{而是在循环中使用1}},或使用collections.OrderedDict()
来使字典记住Python 3.6之前的Python版本上的插入顺序。
答案 2 :(得分:1)
假设您既不能使用外部库也不能使用collections.Counter()
,以下解决方案可能会为您提供帮助:
lis = [['apple', 32], ['Blue shirt', 323], ['Blue shirt', 320]]
d = {}
for (name, count) in lis:
d[name] = d.get('name', 0) + count
lis = [[name, count] for name, count in d.items()]
使用list.count()
的问题在于它仅适用于单个列表,但是您具有列表列表。基本上,我的解决方案使用一个字典,该字典将需要计数的项目作为键,并将计数作为值。然后,我使用列表推导来产生您的期望输出。
答案 3 :(得分:1)
另一种无需任何库(例如collections.Counter
)使用的方法:
lis = [['apple',32],['Blue shirt',323],['Blue shirt',320]]
d = {}
for name, item in lis:
try:
d[name] += item
except KeyError:
d[name] = item
lis = [[k ,v] for k, v in d.items()]
print(lis)
输出:
[['apple', 32], ['Blue shirt', 643]]