如何在Python元组中定义重复项?

How to define duplicate items in a Python tuple?

定义一个由整数组成的元组(其中每个项的出现次数是已知的)的一些好方法是什么?

例如,

我想定义一个具有3 2、2 4和1、3、5的元组出现一次。

为此,我可以一直采用手动方式:

1
foo = (1, 2, 2, 2, 3, 4, 4, 5)

然而,当列表中的项目数量很大时,这会变得有点混乱。所以,我想知道哪些方法可以使生成每个项目所需数量的副本的任务自动化。


你可以这样做:

1
2
>>> (1,) * 1 + (2,) * 3 + (4,) * 2 + (5,) * 1
(1, 2, 2, 2, 4, 4, 5)


如果有一个表示值和频率的元组,可以执行以下操作:

1
2
3
4
tuples = ((1,1), (2,3), (3,1), (4,2), (5,1))

tuple(i for i, n in tuples for _ in range(n)) # Use xrange in Python 2.X
# (1, 2, 2, 2, 3, 4, 4, 5)

或者,如果你知道这些值总是1,2,3,…,n,你可以用enumerate和一组频率。

1
2
3
4
freqs = (1, 3, 1, 2, 1)

tuple(i for i, n in enumerate(freqs, 1) for _ in range(n))
# (1, 2, 2, 2, 3, 4, 4, 5)

如果您对生成器表达式中双重理解的用法感到好奇,那么您可能需要检查这个问题。


一种方法是使用序列乘法。下面是一个简单的版本,它不会试图避免创建不必要的中间对象:

1
2
3
accumulator = ()
for (val, count) in some_data_structure:
    accumulator += (val,) * count

这是可以改进的,重点是证明(1,) * 5给了你(1, 1, 1, 1, 1)。请注意,这复制了对象引用——对于整数来说没问题,但是如果您试图将一系列可变对象相乘,可能会导致混淆。


如果你的元组没有多少个数字,你可以用最简单的方法来做。

1
(1,)+(2,)*3+(3,)+(4,)*2+(5,)

否则,只需将其转换为函数即可。

1
2
3
4
5
def myTuple(*val):
    return sum(((i,) * n for i, n in val), ())

myTuple((1,1),(2,3),(3,1),(4,2),(5,1))
>>>(1, 2, 2, 2, 3, 4, 4, 5)

您也可以通过以下方式调用它:

1
2
3
val = ((1,1),(2,3),(3,1),(4,2),(5,1))
myTuple(*val)
>>>(1, 2, 2, 2, 3, 4, 4, 5)


您可以定义以下函数

1
2
3
4
def a_tuple(*data):
    l = []
    for i, cnt in data: l.extend([i]*cnt)
    return tuple(l)

像这样使用

1
print(a_tuple((1,1), (2,3), (3,1), (4,2), (5,1)))

产生以下输出

1
(1, 2, 2, 2, 3, 4, 4, 5)

如果您不了解函数的工作原理,请查看清单的.extend()方法。


所以你需要EDOCX1的反函数。你可以这样做,

1
2
3
4
5
# make a dict of counts (list of tuples is better)
counts = {1: 1, 2: 3, 4: 2, 3:1, 5: 1}
t = tuple(k for k,v in sorted(counts.items()) for _ in range(v))
(1, 2, 2, 2, 3, 4, 4, 5)
# for k,v in list_of_tuples, for a list of tuples


类似这样的事情可能会奏效:

1
2
3
4
5
>>> result = tuple()
>>> for item, repeat in ((1, 1), (2, 3), (3, 1), (4, 2), (5, 1)):
...    result = result + (item,) * repeat
>>> result
(1, 2, 2, 2, 3, 4, 4, 5)