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

Python 寻找一个更优雅的解决方案,python,Python,返回数组中数字的总和,但忽略以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 从codingbat中寻找更优雅的解决方案。这个答案似乎不那么直观此版本不会修改列表 def sum67(xs): xs = iter(xs) s = 0 for x in xs: if x == 6

返回数组中数字的总和,但忽略以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

从codingbat中寻找更优雅的解决方案。这个答案似乎不那么直观

此版本不会修改列表

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
这还不算太糟(不过你可能会说它太聪明了)

这是一个非常愚蠢的(不适用于负数)

请不要写这样的代码:p

在我离开之前,还有一句可怕的话:

>>> 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
def sum67(nums):
i=0
总和=0
n=len(nums)

而我如果我们可以去掉我们不想要的元素,那么我们可以使用一个简单的求和。以下是一个例子:

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的元素的索引
delnums[i:j+1]
然后删除从
i
j
范围内的元素,包括
j
处的元素。我的解决方案与OP没有太大区别,但总的来说,我喜欢在那里始终有add操作,只需要有逻辑在1和0之间切换“acum”的值

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
如果您对它的工作原理感兴趣,可以使用更具可读性的版本:

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]))
这个怎么样

>>> 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和i或0
中,如果
add
False
,它将进入
部分并求值为
0
,如果
add
True
,它将评估为具有列表理解能力的一行代码:

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):

返回和([x表示索引,x表示枚举(nums)if([nums[(index-nums[index:-1].index(6)):].index(7)+(index-nums[index:-1].index(6))

这修改了原始列表,但效果很好。感谢您让我接触到一些新的
列表
方法@如果您不想修改原始列表,请在方法开头添加
nums=nums[:]
或其他内容。这是一个很好的观点,事实上,我没有真正考虑过更改列表的问题。没有必要给出一个0值。你可以让
for
循环中的第二行成为
,如果不跳过的话:除了挑剔之外,我喜欢它。我特别喜欢这个解决方案与迭代器一起工作,而不必强制使用中间列表@史蒂文哈,我考虑过了。我有点喜欢输入和输出序列的长度相同,但最后这真的没关系。这似乎是对我使用pop方法的严格改进。你能解释一下j=nums.index(7,I)的作用吗?我真的不明白。@MyCarta:我对答案加了一些解释。如果还不清楚,请告诉我。+1这就解释了,谢谢。我很困惑,因为我只知道字符串方法string1.index(string2,begin,end),我更喜欢沃恩的其他解决方案。它不复制列表或任何东西,只是在循环中求和,在找到
6
后使用
index
跳到下一个
7
。IDK如果python解释器/JIT编译器足够聪明,能够看穿这里发生的事情,而不是在删除循环的每个迭代中实际复制数组中的元素。而且每次都要从
i
开始搜索,而不是从
0
开始。像这样的问题要么是关于您是否需要总体改进,要么是您是否希望看到“谜题”的其他解决方案。我投票将此问题作为离题题结束,因为它要求提供“更优雅”的建议工作代码的解决方案,最好是在codereview上。+1这非常棒,但您可以删除
和0
,因为OP说每6个匹配一个7。
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
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]))
>>> 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
def sum67(nums):
  while 6 in nums:
    for x in nums[nums.index(6):]:
      nums.remove(x)
      if x == 7:
        break
  return sum(nums)