有哪些好的方法可以定义一个由整数组成的元组,其中每个项目出现的次数已知?
例如,
我想定义一个元组,包含3个2、2个4和1个3、5,每个数字仅出现一次。
为此,我可以手动进行定义:
foo = (1, 2, 2, 2, 3, 4, 4, 5)
然而,当列表中的项目数量较大时,情况会变得有些混乱。因此,我想知道有哪些方法可以自动化生成每个项目所需数量的副本。
有哪些好的方法可以定义一个由整数组成的元组,其中每个项目出现的次数已知?
例如,
我想定义一个元组,包含3个2、2个4和1个3、5,每个数字仅出现一次。
为此,我可以手动进行定义:
foo = (1, 2, 2, 2, 3, 4, 4, 5)
然而,当列表中的项目数量较大时,情况会变得有些混乱。因此,我想知道有哪些方法可以自动化生成每个项目所需数量的副本。
>>> (1,) * 1 + (2,) * 3 + (4,) * 2 + (5,) * 1
(1, 2, 2, 2, 4, 4, 5)
accumulator = ()
for (val, count) in some_data_structure:
accumulator += (val,) * count
这可以得到改进,主要点是要展示 (1,) * 5
给你的结果是 (1, 1, 1, 1, 1)
。请注意,这会复制对象引用 - 对于整数来说没问题,但如果您试图乘以一系列可变对象,则可能会引起混淆。
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,则可以使用具有频率元组的枚举
。
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)
如果您对生成器表达式中双重理解的使用感到好奇,您可能想查看这个问题。
sum(...,[])
的复杂度是二次的。 - vaultahsum
方法。 - Jared Goguen(1,)+(2,)*3+(3,)+(4,)*2+(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)
val = ((1,1),(2,3),(3,1),(4,2),(5,1))
myTuple(*val)
>>>(1, 2, 2, 2, 3, 4, 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)
所以你想要 collections.Counter
的反函数。这是你可以做到的方法,
# 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
def a_tuple(*data):
l = []
for i, cnt in data: l.extend([i]*cnt)
return tuple(l)
并像这样使用它
print(a_tuple((1,1), (2,3), (3,1), (4,2), (5,1)))
生成以下输出
(1, 2, 2, 2, 3, 4, 4, 5)
如果你不理解该函数的工作原理,可以查看 .extend()
列表方法。