来自不同元组的元素之和

时间:2012-01-10 13:29:26

标签: python tuples

我需要创建一个可以获取元组和数字列表的函数。例: 如果元组列表为[(2,5),(8,9),(11,19),(22,43),(47,50)],且数字为14,则应返回18。 如果包含所有数字,则列表2,3,4,5,8,9,11,12,13,14,15,16,17,18,19...中的数字13的原因为18:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18.

我现在有:

def converting(tuples,index):
    values = [] #I will get [(2,3,4,5,6),(8,9),(11,12,13,14,15,16,17,18,19),(22,..,43),(47,48,49,50)]
    for tuple in tuples: 
        tupleValues = range(tuple[0], tuple[1]+1)
        values.extend(tupleValues)  #ex(2,3,4,5,6)
    if index <= len(values): #If 14 in the example is lower than len of the list, eg 42
        return values[index-1] #return value of 14-1, which is 16?
print converting(14,[(2,5),(8,9),(11,19),(22,43),(47,50)])

当我打印这个时,我收到消息: 对于元组中的元组: TypeError:'int'对象不可迭代

5 个答案:

答案 0 :(得分:3)

这是让你入门的东西。它可以更简洁,但我试图尽可能清楚。如果给定的元组无序,或者索引在值列表中不可用,您还应该考虑要发生的事情。

def valueAtIndex(tuples, index):
  values = []
  for tuple in tuples:
     #range(start, finish) returns a list of integers starting at 'start' and ending at 'finish-1' e.g. range(0, 2) is [0, 1]
     tupleValues = range(tuple[0], tuple[1]+1)
     #Extend adds all of the elements from one list to the end of the other e.g. [0, 1, 2].extend(['a', 'b']) is [0, 1, 2, 'a', 'b']
     values.extend(tupleValues) 
  if index <= len(values):
      return values[index-1]

答案 1 :(得分:2)

这个单行有效:

>>> sorted(reduce(lambda x,y:x.union(set(y)), map(lambda r:range(r[0], r[1]+1), [(2,5),(8,9),(11,19),(22,43),(47,50)]), set()))[13]
18

[(47,50),(22,43),(8,9),(2,5),(11,19)]中的元组顺序无关紧要。

答案 2 :(得分:0)

您可以使用以下单行:

list(itertools.chain.from_iterable([range(start,end+1) for start, end in t]))[13]

其中t是您问题中的元组列表。

解决方案基本上是:

  • 为每个元组生成一个包含range
  • 所包含元素的列表
  • 将结果(列表列表)展平为列表
  • 获取您正在寻找的elemnet

为了更有趣,更懒惰的解决方案是:

next(itertools.islice(itertools.chain.from_iterable(xrange(start,end+1) for start, end in t), 13, None))

答案 3 :(得分:0)

如果我正确理解了问题,你有一系列间隔,你需要从这些间隔中提取第n个数字。以下是有关所用算法的不同解决方案。只需计算间隔序列中所有缺失的数字,并将其添加到您的值中:

tuples = [(2,5),(8,9),(11,19),(22,43),(47,50)]
#tuples = [(2,7),(9,14),(17,20)]

def result(tuple, value):
    start = tuples[0][0] - 1
    for idx in range(len(tuples) - 1):
        if tuples[idx][1] >= value + start:
            break
        start = start + (tuples[idx+1][0] - tuples[idx][1] - 1)  
    return value + start  

for i in range(1, 16):
    print str(i) + ' ' + str(result(tuples, i))

答案 4 :(得分:0)

在致电converting时,您会以相反的顺序传递参数 你应该致电converting([(2,5),(8,9),(11,19),(22,43),(47,50)], 14)