Python列表列表

2024-04-19 00:14:45 发布

您现在位置:Python中文网/ 问答频道 /正文

除了获得理解之外,我没有真正的理由这么做,但我正试图使用列表理解创建列表列表。

我可以很好地创建一个列表列表:

In[1]: [j for j in [range(3,k) for k in [k for k in range(5,10)]]]
Out[1]: [[3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

我可以根据结果创建列表列表,例如:

In [2]: [range(0,i) for i in [3,4]]
Out[2]: [[0, 1, 2], [0, 1, 2, 3]]

In [3]: [range(0,i) for i in j]
Out[3]: 
[[0, 1, 2],
 [0, 1, 2, 3],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4, 5],
 [0, 1, 2, 3, 4, 5, 6],
 [0, 1, 2, 3, 4, 5, 6, 7]]

但当我试图将其合并成一个单独的语句时,它就出错了:

In [4]: [range(0,i) for i in [j for j in [range(3,k) for k in [k for k in range(5,10)]]]]
---------------------------------------------------------------------------
TypeError: range() integer end argument expected, got list.

我是不是丢了一些括号?


Tags: in列表forrangeinteger语句outargument
3条回答

为了解决这个问题,我一次运行列表理解的每个步骤。

>>> [k for k in range(5,10)]
[5, 6, 7, 8, 9]

>>> [range(3,k) for k in [k for k in range(5,10)]]
[[3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

问题就在这里,因为它将列表馈送到下一个range()而不是int:

>>> [j for j in [range(3,k) for k in [k for k in range(5,10)]]]
[[3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

您可以使用lambda展开此列表并减少:

# reduce(lambda x,y: x+y,l)
>>> reduce(lambda x,y: x+y, [range(3,k) for k in [k for k in range(5,10)]])
[3, 4, 3, 4, 5, 3, 4, 5, 6, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 8]

但你仍然只能将两个列表嵌套得很深:

>>> [range(0,i) for i in reduce(lambda x,y: x+y, [range(3,k) for k in [k for k in range(5,10)]])]
[[0, 1, 2], [0, 1, 2, 3], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6, 7]]

如果你想深入研究三个列表,你需要重新考虑你的程序流程。列表理解最适合于处理迭代器中最外层的对象。如果在for语句的左侧和右侧都使用了列表理解,则可以更深入地嵌套:

>>> [[[range(j, 5) for j in range(5)] for i in range(5)] for k in range(5)]

从你的问题:

In[1]: [j for j in [range(3,k) for k in [k for k in range(5,10)]]]
Out[1]: [[3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

range接受整数参数

所以当你这么做的时候

[range(0,i) for i in [j for j in [range(3,k) for k in [k for k in range(5,10)]]]]

这相当于说

L = []
for j in [[3, 4], [3, 4, 5], [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]:
    L.append(range(0,i))

当然,这将失败,因为每个i都是一个list,并且range不接受list参数。

这里的其他答案向您展示了如何修复错误。这个回答是为了解释你最初的方法出了什么问题

希望这有帮助

请尝试以下操作:

[[range(0, j) for j in range(3, i)] for i in range(5, 10)]

这将生成以下列表列表:

>>> pprint.pprint([[range(0, j) for j in range(3, i)] for i in range(5, 10)])
[[[0, 1, 2], [0, 1, 2, 3]],
 [[0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]],
 [[0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]],
 [[0, 1, 2],
  [0, 1, 2, 3],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4, 5],
  [0, 1, 2, 3, 4, 5, 6]],
 [[0, 1, 2],
  [0, 1, 2, 3],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4, 5],
  [0, 1, 2, 3, 4, 5, 6],
  [0, 1, 2, 3, 4, 5, 6, 7]]]

了解列表理解中正在发生的事情的最好方法是尝试将其展开为正常的for循环,让我们用您的和我的尝试看看区别是什么:

x = [range(0,i) for i in [j for j in [range(3,k) for k in [k for k in range(5,10)]]]]
# equivalent to
a, b, c, x = [], [], [], []
for k in range(5, 10):
    a.append(k)
for k in a:
    b.append(range(3, k))
for j in b:
    c.append(j)
for i in c:
    x.append(range(0, i))

最后,这段x将相当于您对列表的理解,但是当然,这段代码不会工作,因为b(和c)将是列表列表,所以i将是列表,并且range(0, i)将导致错误。显然,这不是您想要做的,因为您真正希望看到的是那些for循环,而不是一个接一个地嵌套。

让我们看看我的工作原理:

x = [[range(0, j) for j in range(3, i)] for i in range(5, 10)]
# equivalent to
x = []
for i in range(5, 10):
    a = []
    for j in range(3, i):
        a.append(range(0, j)):
    x.append(a)

希望这有助于澄清!

相关问题 更多 >