当列表项依赖于前面的项时使用函数形式

2024-05-19 02:51:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个元组列表,每个元组都有元素的长度。我使用下面的代码根据前面元素的长度来计算元素的偏移量。你知道吗

import pprint
recordInfo = [(3,), (4,), (1,), (2,)]  # List of lengths
# Calculate and add offsets
recordSize = 0
for index, info in enumerate(recordInfo):
    recordInfo[index] = info + ( recordSize, )  # Replace with new tuple with offset
    recordSize += info[0]  # Calculate next offset
pprint.pprint(recordInfo)

输出为

[(3, 0), (4, 3), (1, 7), (2, 8)]

有没有一种方法可以用函数形式来做循环,比如列表理解?我不知道如何避免临时变量recordSize,这使得它不可能?你知道吗


Tags: 代码importinfo元素列表indexwithlist
3条回答

可能不是你所说的功能性,但嘿,总是很有趣。你知道吗

def increment_record(records, size=0):
     if not records:
         return []
     return [(records[0], size)] + increment_record(records[1:], size=size+records[0])

但是,我不认为这是python真正允许一个人以一种没有本地状态的方式进行寻址的模式(当然,除非您使用前面提到的高级函数)itertools.聚合这只是掩盖了国家)。当然,如果您真的需要,您可以定义某种计数对象(或使用闭包)。你知道吗

class Tallier(object):
     def __init__(self, val):
          self._val = val

     def tally(self, new_val):
          old_val = self._val
          self._val += new_val
          return old_val

[(val, tallier.tally(val)) for val in values]

它不漂亮,也不高效,但下面是一个列表理解,它满足了您的要求:

>>> recordInfo = [(3,), (4,), (1,), (2,)]
>>> [info + (sum(_info[0] for _info in recordInfo[:i]),)
         for i,info in enumerate(recordInfo)]
[(3, 0), (4, 3), (1, 7), (2, 8)]

它的工作原理是在每次迭代时重新计算到当前项的偏移量,因此效率很低。你知道吗

它适用于python2和Python 3。你知道吗

>>> recordInfo = [3, 4, 1, 2]

>>> from functools import reduce
>>> reduce(lambda x, y: x + [(y, sum(x[-1]))], recordInfo, [(0, 0)])[1:]
[(3, 0), (4, 3), (1, 7), (2, 8)]

>>> from itertools import accumulate
>>> list(zip(recordInfo, [0] + list(accumulate(recordInfo))))
[(3, 0), (4, 3), (1, 7), (2, 8)]

如果有元组:

>>> recordInfo = [(3, 'a'), (4, 'b'), (1, 'c'), (2, 'd')]

>>> reduce(lambda x, y: x + [y + (x[-1][0] + x[-1][-1], )], recordInfo, [(0, )])[1:]
[(3, 'a', 0), (4, 'b', 3), (1, 'c', 7), (2, 'd', 8)]

>>> from operator import itemgetter
>>> [x + (c,) for x, c in zip(recordInfo, accumulate(map(itemgetter(0), [(0,)] + recordInfo)))]
[(3, 'a', 0), (4, 'b', 3), (1, 'c', 7), (2, 'd', 8)]

相关问题 更多 >

    热门问题