如何在Python中对元组中的每个值减去1?

6 投票
3 回答
4589 浏览
提问于 2025-04-17 15:49

我有一个用 zip() 创建的元组,现在我想把元组里的每个整数都减去1。我试过这样做,但好像只对列表有效。那么,我该如何在Python中把这个操作改成适用于元组呢?

[...]
lower, upper = zip(*table)
lower[:] = [x + 1 for x in lower]
upper[:] = [x - 1 for x in upper]
holes = zip(lower[:-1], upper[1:])

类型错误:'tuple' 对象不支持项赋值

总的来说,我有一系列不重叠的有序区间存储在 table 里,我需要找出这些区间之间的空隙。比如,我的区间表可能是:

[ 6,  7]
[ 8,  9]
[14, 18]
[23, 32]

我想计算这些区间之间的 holes

[10, 13]
[19, 22]

3 个回答

6

你也可以通过一个简单的列表推导式来解决这些问题:

holes = [(table[i][1]+1, table[i+1][0]-1) for i in range(len(table)-1)]
6

使用 tuple 构造函数和生成器表达式:

lower = tuple(x - 1 for x in lower)
upper = tuple(x + 1 for x in upper)
2

使用生成器函数可以让这个任务变得简单。

table = [(2,3),(5,6),(12,20),(21,25),(28,28),(35,48),(53,55)]

def gaps_between(intervals):
    prec = intervals[0][1] + 1
    for L,H in intervals:
        print '\nprec = %d   (L,H) = (%d,%d)' % (prec,L,H)
        print 'prec = %d <= L-1 = %d : %s' % (prec,L-1,prec<=L)
        if prec<=L-1:
            yield (prec,L-1)
        prec = H + 1
        print 'next prec = %d' % prec

holes = list(gaps_between(table))

print
print 'table =',table
print 'holes =',holes 

在之前的回答中,我使用了在生成器内部定义的迭代器。
为了避免这个问题,我这里用了一种策略:
定义 first prec = first H = intervals[0][1]
因为对于每一对 (L,H),都有 H>=L,所以可以推导出
first H > first L - 1 --> first prec > first L - 1
因此,关于第一个区间的第一次测试总是返回假,真正的处理从第二个区间开始。

prec = 3   (L,H) = (2,3)
prec = 3 <= L-1 = 1 : False
next prec = 4

prec = 4   (L,H) = (5,6)
prec = 4 <= L-1 = 4 : True
next prec = 7

prec = 7   (L,H) = (12,20)
prec = 7 <= L-1 = 11 : True
next prec = 21

prec = 21   (L,H) = (21,25)
prec = 21 <= L-1 = 20 : True
next prec = 26

prec = 26   (L,H) = (28,28)
prec = 26 <= L-1 = 27 : True
next prec = 29

prec = 29   (L,H) = (35,48)
prec = 29 <= L-1 = 34 : True
next prec = 49

prec = 49   (L,H) = (53,55)
prec = 49 <= L-1 = 52 : True
next prec = 56

table = [(2, 3), (5, 6), (12, 20), (21, 25), (28, 28), (35, 48), (53, 55)]
holes = [(4, 4), (7, 11), (26, 27), (29, 34), (49, 52)]

结果是正确的:
- 它给出了 (2,3) 和 (5,6) 之间的间隙 (4,4)
- (12,20) 和 (21,25) 之间没有间隙
- 值 28 在 (28,28) 中,但不在任何间隙里

提问者说这些区间是互不重叠且已排序的。
然而,测试 if prec<=L-1 是必须的,否则相邻的区间会出错:
如果没有这个测试,结果会包含
....., (7, 11), (21, 20), (26, 27), .......

发生的情况是,使用这个强制测试后,以下区间列表
[[ 8, 9],[14, 18],[18, 32]]
[[8, 9], [14, 18], [19, 20], [16, 21], [23, 32]]
这些区间是重叠的(这不是提问者所说的),
如果没有这个测试会出错,
但实际上并没有产生任何错误。

为了让我的代码正确地返回间隙,区间列表必须按照第二个元素进行排序。

.

yield (prec,L-1) 替换为 yield range(prec,L) 会将间隙作为范围返回。

yield (prec,L-1) 替换为 holes.append((prec,L-1)),例如,可以让代码不需要函数。

撰写回答