首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中初始化重复项列表的更优雅的方法

在Python中初始化重复项列表的更优雅的方法
EN

Stack Overflow用户
提问于 2010-06-10 03:16:41
回答 4查看 2.8K关注 0票数 11

如果我想要一个列表初始化为5个零,这是非常好和容易的:

代码语言:javascript
运行
复制
[0] * 5

但是,如果我更改代码以放入更复杂的数据结构,比如一列零:

代码语言:javascript
运行
复制
[[0]] * 5

将不会像预期的那样工作,因为它将是相同列表的10个副本。我要做的是:

代码语言:javascript
运行
复制
[[0] for i in xrange(5)]

这感觉很笨重,而且使用了一个变量,所以有时我甚至会这样做:

代码语言:javascript
运行
复制
[[0] for _ in "     "]

但是,如果我想要一个包含零的列表,它就会变得更加丑陋:

代码语言:javascript
运行
复制
[[[0] for _ in "     "] for _ in "     "]

所有这些,而不是我想要做的:

代码语言:javascript
运行
复制
[[[0]]*5]*5

有没有人找到一个优雅的方法来解决这个“问题”?

EN

Stack Overflow用户

回答已采纳

发布于 2010-06-10 04:10:27

在考虑了一下之后,我想出了这个解决方案:(7行不导入)

代码语言:javascript
运行
复制
# helper
def cl(n, func):
    # return a lambda, that returns a list, where func(tion) is called
    return (lambda: [func() for _ in range(n)])

def matrix(base, *ns):
    # the grid lambda (at the start it returns the base-element)
    grid = lambda: base

    # traverse reversed, to handle the midmost values first
    for n in reversed(ns):
        # assign a new lambda with the last grid within (and call it)
        grid = cl(n, grid)

    return grid() # call the full grid (but the matrix calls you ^^)

测试结果如下:

代码语言:javascript
运行
复制
>>> from pprint import pprint as pp
>>> 
>>> matrix(None, 2,3)
[[None, None, None], [None, None, None]]
>>> 
>>> matrix(None, 4,3)
[[None, None, None], [None, None, None], [None, None, None], [None, None, None]]
>>> 
>>> x = matrix(None, 3,5,2)
>>> pp(x)
[[[None, None], [None, None], [None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None], [None, None], [None, None]]]
>>> x[1][3][0] = "test"
>>> pp(x)
[[[None, None], [None, None], [None, None], [None, None], [None, None]],
 [[None, None], [None, None], [None, None], ['test', None], [None, None]],
 [[None, None], [None, None], [None, None], [None, None], [None, None]]]

另一种解决方案,其优点是使用"[[]*5]*5"-syntax:

代码语言:javascript
运行
复制
def uniq(base, l):
    # function used to replace all values with the base
    nl = []
    for i in l:
        if type(i) is list:
            nl.append(uniq(base, i)) # recursion for deep lists
        else:
            nl.append(base)
    return nl

测试:

代码语言:javascript
运行
复制
# first arg is the base, the 0 inside the [] is just a dummy
# (for what None is the best choice usually)
>>> x = uniq(0, [[[0]]*5]*5)
>>> x[0][3][0] = 5
>>> pp(x)
[[[0], [0], [0], [5], [0]],
 [[0], [0], [0], [0], [0]],
 [[0], [0], [0], [0], [0]],
 [[0], [0], [0], [0], [0]],
 [[0], [0], [0], [0], [0]]]

顺便说一句。numpy库有一个np.zeros(s)-function,其中s是一个类似(3,4,5)的形状

代码语言:javascript
运行
复制
>>> s = (2,2)
>>> np.zeros(s)
array([[ 0.,  0.],
       [ 0.,  0.]])

最后是性能测试:

代码语言:javascript
运行
复制
# functions are already defined ...
import timeit
>>> # Alex Martelli's Code
>>> t1 = timeit.Timer( lambda: multi_dimension_list(None, 3,4,5) )
>>> # the two mentioned above
>>> t2 = timeit.Timer( lambda: matrix(None, 3,4,5) )
>>> t3 = timeit.Timer( lambda: uniq(None, [[[None]*5]*4]*3) )
>>> 
>>> t1.timeit(10000)
2.1910018920898438
>>> t2.timeit(10000)
0.44953203201293945
>>> t3.timeit(10000)
0.48807907104492188

我发现发现这个问题非常有趣。所以,谢谢你的问题:)

票数 9
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3009091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档