为什么我不能从一个列表理解中获得两个列表?

时间:2011-08-18 09:14:08

标签: python

所以我有一个以下形式的数组:

[(1, u'first_type', u'data_gid_1'), 
 (2, u'first_type', u'data_gid_2'), 
 (3, u'first_type', u'data_gid_3'), 
 (4, u'first_type', u'data_gid_4')]

现在我想将每个内部列表的第一个和最后一个元素提取到单独的列表中。所以,如果我这样做:

>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]

这符合我的预期。但是我试图将这两者合并为一个调用,例如:

 (ids, gds) = [(dat[0], dat[2]) for dat in all_data]

然而这失败了:      ValueError: too many values to unpack

所以任何人都可以解释为什么会发生这种情况,如果我想做的话甚至是可能的。

此致 波格丹

4 个答案:

答案 0 :(得分:9)

它不起作用,因为[(dat[0], dat[2]) for dat in all_data]的长度与all_data的长度相同,长度与元组(ids, gds)的长度不同。

请改为尝试:

(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data])

甚至更短:

(ids, gds) = zip(*all_data)[::2]

如另一个答案所述,idsgds现在将成为元组,因此如果您需要列表,请执行以下操作:

(ids, gds) = map(list, zip(*all_data)[::2])



zip(*something)是python中经常出现的习惯用语。如果将列表列表看作矩阵,即

l = [[1, 2, 3],
     [4, 5, 6]]

然后zip(*l)转换该矩阵:

zip(*l) == [(1, 4),
            (2, 5),
            (3, 6)]

*的工作方式如下:some_func(*some_list) 解包 some_list,以便使用some_list元素作为参数调用该函数。因此zip(*l)zip([1, 2, 3], [4, 5, 6])相同。 Here's python教程的相关部分。

zip的作用类似于zipper,因此它的名称,因此它返回一个包含这些元素的列表:给定参数的所有第一个元素的元组,后跟所有第二个元组的元组元素等。

答案 1 :(得分:4)

下面的代码也可以解决问题:

data = [(1, u'first_type', u'data_gid_1'), 
 (2, u'first_type', u'data_gid_2'), 
 (3, u'first_type', u'data_gid_3'), 
 (4, u'first_type', u'data_gid_4')]

ids, gds = ([row[i] for row in data] for i in [0,2])

答案 2 :(得分:1)

[(dat[0], dat[2]) for dat in all_data]表示您正在创建元组(dat[0],dat[2])列表。这并不意味着您有两个列表,一个是d[0],另一个是d[2]

您可以简单地使用zip,但这会导致元组。如果您需要列表,则必须将list应用于结果:

(ids, gds) = map(list,zip(*[(dat[0], dat[2]) for dat in a]))

答案 3 :(得分:0)

由于您要创建两个单独的列表,请尝试以下方法:

ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data]

或者您可以使用您使用的命令将其解压缩到单个列表中:

x = [(dat[0], dat[2]) for dat in all_data]
相关问题