【问题标题】:Some built-in to pad a list in python一些内置在python中填充列表
【发布时间】:2011-03-27 05:01:03
【问题描述】:

我有一个大小为 N 的列表,我想用一个值将它填充到大小为 N。

当然,我可以使用类似以下的东西,但我觉得应该有一些我错过的东西:

>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']

【问题讨论】:

  • 为什么要这样做?可能有更好的方法。
  • 我将列表序列化为具有固定列数的制表符分隔字符串。
  • 你的意思是你正在做类似'\t'.join([1,'','','',''])的事情吗?也许您可以告诉我们更多关于您打算实施的内容,然后我们可以尝试提出一个想法。
  • @Satoru.Logic: 是的,print >> a_stream, '\t'.join(the_list) 就是我想要实现的全部

标签: python list list-manipulation


【解决方案1】:
a += [''] * (N - len(a))

或者如果您不想在原地更改a

new_a = a + [''] * (N - len(a))

你总是可以创建一个 list 的子类并调用任何你喜欢的方法

class MyList(list):
    def ljust(self, n, fillvalue=''):
        return self + [fillvalue] * (n - len(self))

a = MyList(['1'])
b = a.ljust(5, '')

【讨论】:

  • 这看起来好多了,但我仍然期待像 fillpad 方法或函数 =)
  • 糟糕...TypeError: object of type 'int' has no len()
【解决方案2】:

我认为这种方法更直观和 Pythonic。

a = (a + N * [''])[:N]

【讨论】:

  • 这需要我半分钟才能理解。接受的答案要简单得多。
  • @RichardMöhn “pythonic”的意思是“惯用语”。你使用 Python 的时间越长,你就会越自然地发现这种语法。
  • 我知道“pythonic”是什么意思。而且我从 2014 年开始就一直在使用 Python。我仍然不觉得你的答案很自然。
  • 是什么让构建中间丢弃列表变得像 Python 一样?
  • @DylanYoung 这不是第一次N < len(a) 时的情况。您提供的第二个答案就是这种情况。
【解决方案3】:

没有用于此的内置函数。但是您可以为您的任务(或任何东西:p)编写内置插件。

(修改自 itertool 的 padnonetake 配方)

from itertools import chain, repeat, islice

def pad_infinite(iterable, padding=None):
   return chain(iterable, repeat(padding))

def pad(iterable, size, padding=None):
   return islice(pad_infinite(iterable, padding), size)

用法:

>>> list(pad([1,2,3], 7, ''))
[1, 2, 3, '', '', '', '']

【讨论】:

  • 不错的方法:chain(iterable, repeat(padding))
【解决方案4】:

more-itertools 是一个库,其中包含用于解决此类问题的特殊 padded 工具:

import more_itertools as mit

list(mit.padded(a, "", N))
# [1, '', '', '', '']

另外,more_itertools 还实现了 Python itertools recipes,包括 @kennytm 提到的 padnonetake,因此不必重新实现它们:

list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]

如果您希望替换默认的 None 填充,请使用列表推导:

["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']

【讨论】:

    【解决方案5】:

    gnibbler 的回答更好,但是如果你需要一个内置函数,你可以使用itertools.izip_longest(Py3k 中的zip_longest):

    itertools.izip_longest( xrange( N ), list )
    

    这将返回一个元组列表 ( i, list[ i ] ) 填充为 None。如果您需要摆脱计数器,请执行以下操作:

    map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
    

    【讨论】:

    • 我知道 izip_longest 但导致代码看起来不太好 =)
    • 我相信你的意思是operator.itemgetter()None 的值也需要替换为 ""
    【解决方案6】:

    您也可以使用没有任何内置插件的简单生成器。 但我不会填充列表,而是让应用程序逻辑处理一个空列表。

    总之,没有内置的迭代器

    def pad(iterable, padding='.', length=7):
        '''
        >>> iterable = [1,2,3]
        >>> list(pad(iterable))
        [1, 2, 3, '.', '.', '.', '.']
        '''
        for count, i in enumerate(iterable):
            yield i
        while count < length - 1:
            count += 1
            yield padding
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    

    【讨论】:

      【解决方案7】:

      如果你想用 None 而不是 '' 填充,map() 就可以了:

      >>> map(None,[1,2,3],xrange(7))
      
      [(1, 0), (2, 1), (3, 2), (None, 3), (None, 4), (None, 5), (None, 6)]
      
      >>> zip(*map(None,[1,2,3],xrange(7)))[0]
      
      (1, 2, 3, None, None, None, None)
      

      【讨论】:

      • 坦率地说,a+['']*(N-len(a))看起来清晰多了。此外,它缺乏列表。不过还是谢谢你。
      【解决方案8】:

      离开 kennytm:

      def pad(l, size, padding):
          return l + [padding] * abs((len(l)-size))
      
      >>> l = [1,2,3]
      >>> pad(l, 7, 0)
      [1, 2, 3, 0, 0, 0, 0]
      

      【讨论】:

        【解决方案9】:
        extra_length = desired_length - len(l)
        l.extend(value for _ in range(extra_length))
        

        这避免了任何额外的分配,这与任何依赖于创建和附加列表[value] * extra_length 的解决方案不同。 “extend”方法首先在迭代器上调用__length_hint__,然后将l 的分配扩展这么多,然后再从迭代器中填充它。

        【讨论】:

        • 更简洁地说,a.extend((N-len(a))*[padding_value])(我使用的是 OP 表示法)。
        • 您的提议涉及分配一个列表,然后使用“扩展”来附加它。我的避免了额外的分配;没有创建新列表,只有一个生成器对象。
        【解决方案10】:

        你可以使用*iterable unpacking operator:

        N = 5
        a = [1]
        
        pad_value = ''
        pad_size = N - len(a)
        
        final_list = [*a, *[pad_value] * pad_size]
        print(final_list)
        

        输出:

        [1, '', '', '', '']
        

        【讨论】:

          【解决方案11】:

          使用迭代器并利用 nextdefault 参数:

          i = iter(a)
          a = [next(i, '') for _ in range(N)]
          

          简短说明:

          无论哪种方式,我们都想生产N 项目。因此for _ in range(N)。那么元素应该尽可能多地来自a,其余的''。在a 上使用迭代器,我们抓取所有可能的元素,当我们得到StopIteration 时,将返回默认,即''

          【讨论】:

            【解决方案12】:

            使用np.repeat添加到现有列表:

            import numpy as np
            a + list(np.repeat([''], (N - len(a))))
            

            【讨论】:

              【解决方案13】:

              在元素列表之前添加填充

              a[:0] += [''] * (N - len(a))
              

              在元素列表之后添加填充

              a += [''] * (N - len(a))
              

              【讨论】:

                【解决方案14】:

                一种用空元素填充列表的 Pythonic 方法是使用列表推导。

                        my_list = [1,2]
                        desired_len = 3
                        # Ensure that the length of my list is 3 elements
                        [my_list.extend(['']) for _ in range(desired_len - len(my_list))]
                        [my_list.pop() for _ in range(len(my_list)-desired_len )]
                

                【讨论】:

                  猜你喜欢
                  • 2010-10-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-12-04
                  • 2012-04-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-15
                  • 2017-08-27
                  相关资源
                  最近更新 更多