寻找一个更优雅的解决方案

问题描述:

返回数组的总和,除了忽略以6开头的数字部分并延伸到下一个7(每6个会跟着至少一个7) 。没有号码返回0。寻找一个更优雅的解决方案

sum67([1, 2, 2]) ? 5 
sum67([1, 2, 2, 6, 99, 99, 7]) ? 5 
sum67([1, 1, 6, 7, 2]) ? 4 
def sum67(nums): 
    dontadd = 0 
    sum = 0 
    for i in range(0, len(nums)): 
     if dontadd == 0: 
      if nums[i] == 6: 
       dontadd = 1 
      else: 
       sum += nums[i] 
     else: 
      if nums[i] == 7: 
       dontadd = 0 
      else: 
       pass# nothing happens. It is useful as a placeholder when a statement is required syntactically 
    return sum 

寻找从codingbat一个更优雅的解决这个问题。这个答案似乎并不直观,因为它可能是

+2

类似这样的问题属于无论是在http://codereview.stackexchange.com/如果你想要全面改善,或http:// codegolf.stackexchange.com/如果你想看到其他解决方案的“难题” – agf 2012-04-17 05:19:58

+2

我正在投票关闭这个问题作为题外话,因为它要求推荐一个“更优雅”的解决方案的工作代码,它应该最好在codereview上。 – 2016-10-28 14:42:47

如果我们可以删除我们不想要的元素,那么我们可以使用一个简单的总和。这里是一个例子:

def sum67(nums): 
    nums=nums[:] 
    while 6 in nums: 
     i=nums.index(6) 
     j=nums.index(7,i) 
     del nums[i:j+1] 
    return sum(nums) 

首先,我们使用nums=nums[:]复制。来电者可能不希望nums更改。

nums.index(6)找到值为6的第一个元素的索引。nums.index(7,i)找到索引为i后第一个具有值7的元素的索引。 del nums[i:j+1]然后删除范围从ij的元素,包括j处的元素。

+0

我喜欢干净的简单。 – steveha 2012-04-17 04:15:12

+0

这似乎是对我使用pop的方法的严格改进。 – 2012-04-17 04:17:07

+0

是的,这是一个不错的 – davidjglynn 2012-04-17 05:04:58

此版本不会修改列表。

def sum67(xs): 
    xs = iter(xs) 
    s = 0 
    for x in xs: 
    if x == 6: 
     while x != 7: 
      x = xs.next() 
    else: 
     s += x 
    return s 

这是不是太糟糕(你可能认为它试图太聪明,虽然)。

>>> def sum67(nums): 
...  while 6 in nums: 
...   index = nums.index(6) 
...   while nums.pop(index) != 7: 
...    pass 
...  return sum(nums) 
... 
>>> sum67([1, 2, 3]) 
6 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 1, 6, 7, 2]) 
4 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 

这里是一个非常愚蠢的一个(不会与负数工作)

>>> import re 
>>> def sum67(nums): 
...  return sum(int(j) for j in re.sub(r'6\d*?7', '', ''.join((str(i) for i in nums)))) 
>>> sum67([1, 2, 3]) 
6 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, 7, 2]) 
16 

请永远不要写这样的代码:对

一个更可怕的一个班轮在我离开之前单凭这一点:

>>> def sum67(nums): 
...  return sum(i if i != 6 else -sum(nums[pos+1:nums.index(7,pos)+1]) for pos, i in enumerate(nums)) 
... 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 
+0

这会修改原始列表,但效果很好。感谢您向我公开一些新的'list'方法! – 2012-04-17 03:55:34

+0

@MarkRansom如果你不想修改原来的列表,你可以在方法的开始放置'nums = nums [:]'或其他东西。实际上这是一个好点,我没有真正想过更改列表的问题。 – 2012-04-17 03:56:41

def sum67(nums): 
    i=0 
    sum=0 
    n=len(nums) 
    while i<n: 
    if nums[i]==6: 
     i=nums.index(7,i) 
    else: 
     sum += nums[i] 
    i+=1 
    return sum 

我的解决方案将无法从OP太大的不同,但总的来说,我喜欢的总是有存在的添加操作,只是有逻辑切换1和0

之间的“ACCUM”的价值理念
def sum67(nbrs): 
    total = 0 
    accum = 1 
    for nbr in nbrs: 
     if nbr==6: 
      accum=0 
     total += nbr*accum 
     if accum==0 and nbr==7: 
      accum=1 
    return total 

这里是可以容易理解的一个版本:

def sum67(nums): 
    found6 = False 
    result = 0 
    for n in nums: 
     if n==6: 
      found6 = True 
      continue 
     if n==7 and found6: 
      found6 = False 
      continue 
     if not found6: 
      result += n 
    return result 

我最喜欢的Python的事情是,它使得它很容易打散的一个问题。

def skip67(seq): 
    skipping = False 
    for value in seq: 
     skipping = skipping or value == 6 
     yield 0 if skipping else value 
     skipping = skipping and value != 7 

def sum67(seq): 
    return sum(skip67(seq)) 

>>> sum67([1, 2, 2]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 1, 6, 7, 2]) 
4 
+2

没有必要产生0值。你可以在'for'循环中做第二行,就是'如果不跳过:yield value'除了挑选,我喜欢它。特别是我喜欢这个解决方案可以与迭代器一起工作,而不需要强制中间列表! – steveha 2012-04-17 04:11:33

+0

@steveha,我认为。我有点喜欢输入和输出序列长度相同,但最终它并不重要。 – 2012-04-17 04:13:07

def sum67(L): 
    it = iter(L) 
    return sum(all(i!=7 for i in it) if i == 6 else i for i in it) 

如果你有兴趣在如何工作稍微更可读的版本:

def slice67(L): 
    it = iter(L) 

    for i in it: 
     if i != 6: 
      yield i 
     else: 
      while next(it, 7) != 7: 
       pass 

print sum(slice67([1, 2, 2])) 
+0

+1这真棒,但你可以删除'和0',因为OP说每6个匹配一个7。 – jamylak 2012-04-17 05:46:58

这个怎么样?

>>> def sum67(l): 
...  sum = 0 
...  add = True 
...  for i in l: 
...   add = add and (i != 6) 
...   sum += add and i or 0 
...   add = add or i == 7 
...  return sum 
... 
>>> print sum67([1, 2, 3]) 
6 
>>> print sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> print sum67([1, 1, 6, 7, 2]) 
4 
>>> print sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 

它利用了Python计算布尔表达式第一操作数的值确定的结果,例如,实际上,在sum += add and i or 0,如果addFalse,它进入or部分和的计算结果为0,如果add分别为True,则评估为i

def sum67(nums): 
    while 6 in nums: 
    for x in nums[nums.index(6):]: 
     nums.remove(x) 
     if x == 7: 
     break 
    return sum(nums) 

一个班轮与列表解析:

def sum67(nums): return sum([x for index, x in enumerate(nums) if (((nums[(index - nums[index::-1].index(6)):].index(7) + (index - nums[index::-1].index(6))) < index) if (6 in nums[:index+1]) else True)])