【问题标题】:Create List With Numbers Getting Greater Each Time Python [closed]每次Python都创建数字越来越大的列表[关闭]
【发布时间】:2012-10-25 12:40:19
【问题描述】:

我怎样才能创建一个函数来创建一个列表,将它每次包含的数字数量增加到一个指定的值?

例如,如果最大值为 4,则列表将包含

1, 2, 2, 3, 3, 3, 4, 4, 4, 4

很难解释我在寻找什么,但从这个例子中我想你会明白的!

谢谢

【问题讨论】:

  • 好的,你试过什么?
  • 嗯,你必须跟踪调用这个函数的次数。您可以使用全局变量或在函数中传递并在每次调用后递增的静态变量来执行此操作。
  • 你想要f(2) -> [1, 2, 2]吗?
  • 这个问题我其实没看懂))
  • ...没有尝试示例,我觉得我们只是做了 OP 的作业...

标签: python list loops while-loop


【解决方案1】:

我会使用itertools.chain:

itertools.chain(*([i] * i for i in range(1, 5)))

itertools.chain.from_iterable 稍微懒一点:

itertools.chain.from_iterable([i] * i for i in range(1, 5))

对于终极懒惰,与itertools.repeat 配对——(在您使用python2.x 时使用xrange):

import itertools as it
it.chain.from_iterable(it.repeat(i, i) for i in range(1, 5))

作为一个函数:

def lazy_funny_iter(n):
    return it.chain.from_iterable(it.repeat(i, i) for i in range(1, n+1))

def lazy_funny_list(n):
    return list(lazy_funny_iter(n))

【讨论】:

  • +1 根据提问者的需要,您也可以用itertools.count() 替换范围,因为您做所有事情都是懒惰的。
  • @NeilG -- 感谢您的支持。 count 似乎在这里使用会很棘手。我的印象是它可以无限期地计算——这使得它很难与其他东西联系起来。 xrange 在 py2k 中是惰性的,range 在 py3k 中是惰性的,所以得到一个惰性的 range-like 函数应该没有问题。
  • 是的,我只是在想,如果序列的使用者使用有限序列压缩它,那么无限期地计数可以节省调用者必须传递参数。
【解决方案2】:

一个嵌套循环。 这将是一种非常基本的方法。 有很多更好的方法,这应该会给你一个大致的想法。

>>> def listmaker(num):
    l = []
    for i in xrange(1, num+1):
        for j in xrange(i):
            l.append(i)
    return l

>>> print listmaker(4)
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

这里是用列表理解来做的:

>>> def listmaker2(num):
    return [y for z in [[x]*(x) for x in xrange(1, num+1)] for y in z]

>>> print listmaker2(4)
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

按照建议使用扩展。

>>> def listmaker3(num):
    l = []
    for i in xrange(1, num+1):
        l.extend([i]*(i))
    return l

>>> print listmaker3(4)
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

【讨论】:

  • 为什么不使用“扩展”?如果最终数据不需要排序,它应该会降低复杂度
  • @luke14free 我不明白您希望我在我的代码中的哪个位置执行此操作。一个不同的解决方案可以使用扩展,也许我会写一个。
  • @luke14free -- 问题陈述中没有任何内容暗示最终数据不需要排序。当然,您可以使用for i in xrange(1,num+1) 作为外循环来执行l.extend([i]*i)
  • @mgilson 感谢您提醒我,我可以将 xrange 设置为从 1 开始。要编辑。
  • @InbarRose -- 您也可以将其添加到原始答案中,以避免不必要的空循环。
【解决方案3】:

你可以使用递归函数:

def my_func(x):
    if x <= 0:
        return []
    else:
        return my_func(x-1) + [x] * x

>>> my_func(4)
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

【讨论】:

    【解决方案4】:
    In [1]: def funny_list(n):
       ...:     return sum(([i]*i for i in range(1, n+1)), [])
       ...: 
    
    In [2]: funny_list(4)
    Out[2]: [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
    

    不过,这不能变成真正的生成器,这与 itertools.chain 不同,后者是规范的方式。

    【讨论】:

    • sum的有趣用法
    • 以这种方式使用sum 时要注意的一点是,它会显示二次行为,因此如果n 是(比如说)100,它将花费比@987654326 长数百倍的时间@。当然,通常这并不重要。
    • @DSM 啊。是的。对每个数组求和:)
    【解决方案5】:

    对问题的不同看法(稍微简单一点):

    >>> a = range(1,5)
    >>> for i in range(2,5):
    ...     a.extend(range(i,5))
    ... 
    >>> print sorted(a) #Remove the sort if you don't need it
    [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
    

    【讨论】:

      【解决方案6】:

      如图所示创建列表的一种相当直接的方法是通过

      [i for i in range(1,n+1) for j in range(i)]
      

      其中n 是列表中出现的最大数字。以上等价于之前几个建议的答案中使用的方法,但表达方式稍微干净一些。

      到目前为止提到的所有方法的替代方法是注意列表的ith 元素大约等于2*i 平方根的整数部分。稍作调整,这使得一个相当简单的生成器成为可能,如下所示。

      def gen_nnlist(nmax):
          n = 1
          while n < nmax*(nmax+1):
              yield int(n**.5+.5)
              n += 2
      

      以下是在 python 2.7.3 解释器中执行代码的一些示例输出:

      >>> print [i for i in gen_nnlist(4)]
      [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
      >>> print [i for i in gen_nnlist(6)]
      [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6]
      >>> fun = gen_nnlist(3)
      >>> for i in fun: print i
      ... 
      1
      2
      2
      3
      3
      3
      >>>
      

      【讨论】:

      • +1 以获得最干净的答案。令人惊讶的是,我不知道列表组合可以像这样以平面方式嵌套。这有点酷,虽然我确定我会忘记哪个循环在里面,哪个循环在外面......
      【解决方案7】:
      >>> list(''.join([str(x) * x for x in range(1, 5)]))
      

      【讨论】:

        【解决方案8】:

        我会使用发电机:

        >>> def growingSeq(maxN):
        ...     for n in range(1,maxN+1):
        ...         for _ in range(n):
        ...             yield n
        ... 
        >>> growingSeq(4)
        <generator object growingSeq at 0x1004db280>
        >>> list(growingSeq(4))
        [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
        

        【讨论】:

        • 如果我们真的想要生成器,请使用 xrange 而不是 range 语法。
        • 在大多数实际用例中,输入和阅读range 而不是xrange 的便利性将比两者之间的运行时差异节省更多时间。加上 Python 3。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-02
        相关资源
        最近更新 更多