【问题标题】:sequence of repeated values in a list列表中重复值的序列
【发布时间】:2019-05-07 05:54:06
【问题描述】:

我的程序有问题,希望有人能帮我解决这个问题。基本上我有一个包含 20 个值的随机生成列表,我想将重复的值放在括号之间(例如,如果列表是 [1,2,2,4,5] 它应该显示 1 ( 2 2 ) 4 5 ) 现在这是我的代码,只有在最后没有重复值的情况下才有效,因为列表索引超出了范围。我该如何解决这个问题?

from random import randint
lanci = []
for i in range(20):
    x = randint(1,6)
    lanci.append(x)
print(lanci)
i=0
while i < len(lanci)-1):
    if lanci[i] == lanci[i+1]:
        print("(",end=" ")
        print(lanci[i],end=" ")
        while lanci[i]==lanci[i+1]:
            i = i + 1 
            print(lanci[i],end=" ")
    print(")",end=" ")
else:
    print(lanci[i],end=" ")
    i = i + 1  

【问题讨论】:

  • 首先,您需要修复整个提供的 sn-p 中的语法错误。例如: print(lanci[i],end=" " 不以 ) 结尾。 while i
  • 好的,谢谢我修复了它们,虽然我没有复制粘贴,但我复制了它,这就是它有语法错误的原因。但问题是,如果列表的最后一个值在重复序列中,它会给我索引 i 超出范围,但我无法修复它。
  • itertools.groupby 的帮助下,我将开始将[1, 2, 2, 4, 5] 变成[1, [2, 2], 4, 5]。然后应该是一个简单的练习,将整数转换为字符串,将子列表转换为带括号的序列。 (就像我打字时 tobias_k 所做的那样:))
  • [1,2,2,4,5,6] 所需的输出是什么?

标签: python arrays python-3.x list


【解决方案1】:

这是另一个仅使用基本列表的选项:

def group_consecutives(lst):
  res, sub, memo = [None], [], None
  lst.append(memo)
  for x in lst:
    if memo == x:
      sub.append(memo)
      if res[-1] != sub: res.append(sub)
    else:
      sub.append(memo)
      if memo and not len(sub) > 1: res.append(memo)
      memo, sub = x, []
  return res[1:]

print(group_consecutives(lanci))

【讨论】:

    【解决方案2】:

    将数字列表转换为字符串,然后您可以使用此功能。 如果您再次需要列表,请将其拆分。

    def add_brackets(string):
        _character, _index = None, 0
        _return_string = ''
        for i, c in enumerate(string+ ' '):
            if _character is None or _character != c :
                if len(string[_index:i])>1:
                    _return_string+='(' + string[_index: i] + ')'
                else:
                    _return_string+=string[_index: i]
                _character, _index = c, i
        return _return_string
    

    【讨论】:

    • 先把列表转成字符串的目的是什么?这不会很难,例如多位数字,更不用说其他东西的列表(例如字符串列表)?另外,字符串输入会是什么样子? str(lst),或''.join(lst),或如何?
    • 因为最终输出是一个字符串,否则您可以使用返回列表而不是 _return_string... 而不是添加到字符串,您可以追加/扩展列表。对于多位数字,必须仅将其作为列表处理。要转换为字符串,您必须将数字映射到字符串连接。但这仅在数字仅为个位数时才有用。在示例中,数字仅在 1-6 之间
    • 这很清楚。问题是,您写的是您希望输入为字符串,显然该字符串的格式很重要,并且字符串的外观有很多不同的方式(请参阅第一条评论),但您从不说 如何 它应该看起来,或者举个例子。没有它,这个解决方案就无法真正测试,更不用说可用了。
    • 谢谢,你说得很好。我认为为了使其更适用于指定的问题,可以对其进行修改,并且应该接受一个列表并进行相应的处理。
    【解决方案3】:

    只需在您的内部 while 循环之前检查“最后一个元素”。

    from random import randint
    
    lanci = []
    for i in range(20):
        x = randint(1,6)
        lanci.append(x)
    print(lanci)
    i=0
    while i < len(lanci)-1):
        if lanci[i] == lanci[i+1]:
            print("(",end=" ")
            print(lanci[i],end=" ")
            while (i+1 < len(lanci)) and (lanci[i]==lanci[i+1]):
                i = i + 1 
                print(lanci[i],end=" ")
        print(")",end=" ")
        else:
            print(lanci[i],end=" ")
            i = i + 1
    

    【讨论】:

    • 天哪,我不知道如果你给出两个虚假陈述,它会在第一个停止并且不检查另一个,非常感谢!!!!
    • @Tyler99,是的,这是一个非常方便的功能:它可以让你拥有一个 if 语句/块,而不必嵌套——更易读,更频繁。
    【解决方案4】:

    不是最漂亮但会做到的:

    from random import randint
    from itertools import groupby
    
    lanci = [randint(1,6) for _ in range(20)]
    
    result = [tuple(v) for _, v in groupby(lanci)]
    
    print(*[i[0] if len(i) == 1 else '('+' '.join(map(str, i))+')' for i in result], sep=' ')
    #(2 2) 3 5 3 1 5 4 6 2 1 4 6 4 (5 5) 3 6 3 4
    

    【讨论】:

      【解决方案5】:

      除了您更手动的方法之外,您可以使用 itertools.groupby 将列表中的相等值分组,然后将它们括在括号中:

      >>> import random, itertools
      >>> lst = [random.randint(1, 5) for _ in range(20)]
      >>> tmp = [list(map(str, g)) for k, g in itertools.groupby(lst)]
      >>> ' '.join(g[0] if len(g) == 1 else "(" + " ".join(g) + ")" for g in tmp)
      '5 4 1 2 1 4 (5 5) 4 5 1 5 4 3 (5 5) 3 (5 5 5)'
      

      【讨论】:

      • tmp = [g for _, g in itertools.groupby(map(str, lst))]。无需将 g 转换为列表,因为您只需立即迭代它们。
      • @chepner 是的,但您无法获得 groupy-group 的 len,对吧? (tmp 不一定是列表,也可以是生成器,我只是想提供一种简单的方法来查看组,同时避免在查看后出现关于生成器耗尽的明显后续问题)
      • 有趣的是,我们如何做到几乎相同的事情,为你 +1!
      • @zipa 引用import this:“应该有一种——最好只有一种——明显的方法。” :-)
      • @tobias_k 啊,对,在这​​种情况下,join 的生成器表达式中需要类似 ... for g in map(list, tmp) 的内容。
      猜你喜欢
      • 1970-01-01
      • 2015-04-01
      • 2022-01-05
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多