我有一个包含字符串和整数的混合列表,我需要了解每个字符串之间的数字总和。理想情况下,最终结果将是一个元组列表,因为每个字符串和后面的数字都在一起(因此顺序很重要)。
我可以使用isinstance
通过迭代来提取数字,但是实际列表很大,有时每个字符串有1或2个数字。
my_list = ['a', 2, 1, 'b', 3, 'h', 50, 4, 'd', 4, 'v', 20, 7]
ideal_output = [('a', 3) ('b', 3), ('h', 54), ('d', 4), (v, 27)]
答案 0 :(得分:2)
这是使用itertools.groupby的解决方案:
my_list = ['a', 2, 1, 'b', 3, 'h', 50, 4, 'd', 4, 'v', 20, 7]
from itertools import groupby
groups = groupby(my_list, key=type) # group-by the type of the value
result = []
for key, group in groups:
string = next(group) # get the string first, we'll skip over it otherwise
if key is str:
_, values = next(groups) # move the generator forward to get to the numbers
result.append((string, sum(values))) # sum up the numbers
print(result)
输出:
[('a', 3), ('b', 3), ('h', 54), ('d', 4), ('v', 27)]
它确实假定字符串之间至少有一个数字。如果不是,则可以检查len
的{{1}},如果大于1,请为g
答案 1 :(得分:0)
您也可以不使用groupby
就使用简单的迭代,这会稍快一些,因为它只进行一次遍历:
my_list = ['a', 2, 1, 'b', 3, 'h', 50, 4, 'd', 4, 'v', 20, 7]
new_list = []
new_element = []
for element in my_list:
if isinstance(element, str):
if new_element:
new_list.append(tuple(new_element))
new_element = [element, 0]
else:
new_element[1] += element
if new_element:
new_list.append(new_element)
print(new_list)
输出:
[('a', 3), ('b', 3), ('h', 54), ('d', 4), ('v', 27)]
答案 2 :(得分:0)
具有functools.reduce功能:
from functools import reduce
def accum(prev, curr): # prev - previous item, curr - current item
if prev == [] or isinstance(curr, str):
prev.append((curr, 0))
elif isinstance(curr, int):
prev[-1] = (prev[-1][0], prev[-1][1] + curr)
return prev
my_list = ['a', 2, 1, 'b', 3, 'h', 50, 4, 'd', 4, 'v', 20, 7]
res = reduce(accum, my_list, []) # [] is initializer
print(res)
输出:
[('a', 3), ('b', 3), ('h', 54), ('d', 4), ('v', 27)]