So I have an array of the following form:
所以我有一个以下形式的数组:
[(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')]
Now I want to extract the first and the last element of each inside list into separate lists. So if I do:
现在我想将每个内部列表的第一个和最后一个元素提取到单独的列表中。所以,如果我这样做:
>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]
This works as I expect it to. However I was trying to merge these two into one call, something like:
这符合我的预期。但是我试图将这两个合并为一个调用,例如:
(ids, gds) = [(dat[0], dat[2]) for dat in all_data]
This however fails with an: ValueError: too many values to unpack
然而,这失败了:ValueError:要解压缩的值太多
So could anyone explain why this is happening and if what I am trying to do is even possible.
所以任何人都可以解释为什么会发生这种情况,如果我想做的话甚至是可能的。
Regards, Bogdan
4 个解决方案
#1
8
It doesn't work because the length of [(dat[0], dat[2]) for dat in all_data]
is the same as the lenght of all_data
, which is not the same length as the tuple (ids, gds)
.
它不起作用,因为all_data中dat的[(dat [0],dat [2])的长度与all_data的长度相同,它与元组(ids,gds)的长度不同。
Try this instead:
试试这个:
(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data])
or even shorter:
甚至更短:
(ids, gds) = zip(*all_data)[::2]
As noted in another answer, ids
and gds
will now be tuples, so if you need lists, do like this:
如另一个答案所述,ids和gds现在将成为元组,因此如果您需要列表,请执行以下操作:
(ids, gds) = map(list, zip(*all_data)[::2])
The zip(*something)
is a rather frequently occuring idiom in python. If you look at a list of lists as a matrix, i.e.
zip(* something)是python中经常出现的习惯用语。如果你看一个列表列表作为矩阵,即
l = [[1, 2, 3],
[4, 5, 6]]
Then zip(*l)
transposes that matrix:
然后zip(* l)转置该矩阵:
zip(*l) == [(1, 4),
(2, 5),
(3, 6)]
The *
works like this: some_func(*some_list)
unpacks some_list
so that the function is in effect called with the elements of some_list
as arguments. So zip(*l)
is the same as zip([1, 2, 3], [4, 5, 6])
. Here's the relevant part of the python tutorial.
*的工作方式如下:some_func(* some_list)解包some_list,以便使用some_list的元素作为参数调用该函数。因此zip(* l)与zip([1,2,3],[4,5,6])相同。这是python教程的相关部分。
zip
acts like a zipper, hence the name, so it returns a list with these elements: a tuple of all the first elements of the given arguments, followed by a tuple of all the second elements, etc.
zip就像一个拉链,因此得名,所以它返回一个包含这些元素的列表:给定参数的所有第一个元素的元组,后跟所有第二个元素的元组,等等。
#2
4
Code below will also do the trick:
下面的代码也可以解决问题:
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])
#3
1
[(dat[0], dat[2]) for dat in all_data]
means that you're creating a list of tuples (dat[0],dat[2])
. It does not mean you have two lists, one of d[0]
and the other of d[2]
.
[(dat [0],dat [2])for all_data中的dat]表示您正在创建元组列表(dat [0],dat [2])。这并不意味着你有两个列表,一个是d [0],另一个是d [2]。
You could simply use zip
, but that will result in tuples. If you want lists, you'll have to apply list
to the result:
你可以简单地使用zip,但这将导致元组。如果您需要列表,则必须将列表应用于结果:
(ids, gds) = map(list,zip(*[(dat[0], dat[2]) for dat in a]))
#4
0
Since you are creating two separate lists, try this:
由于您要创建两个单独的列表,请尝试以下操作:
ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data]
or you can unpack it to a single list with the command you used:
或者您可以使用您使用的命令将其解压缩到单个列表:
x = [(dat[0], dat[2]) for dat in all_data]
#1
8
It doesn't work because the length of [(dat[0], dat[2]) for dat in all_data]
is the same as the lenght of all_data
, which is not the same length as the tuple (ids, gds)
.
它不起作用,因为all_data中dat的[(dat [0],dat [2])的长度与all_data的长度相同,它与元组(ids,gds)的长度不同。
Try this instead:
试试这个:
(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data])
or even shorter:
甚至更短:
(ids, gds) = zip(*all_data)[::2]
As noted in another answer, ids
and gds
will now be tuples, so if you need lists, do like this:
如另一个答案所述,ids和gds现在将成为元组,因此如果您需要列表,请执行以下操作:
(ids, gds) = map(list, zip(*all_data)[::2])
The zip(*something)
is a rather frequently occuring idiom in python. If you look at a list of lists as a matrix, i.e.
zip(* something)是python中经常出现的习惯用语。如果你看一个列表列表作为矩阵,即
l = [[1, 2, 3],
[4, 5, 6]]
Then zip(*l)
transposes that matrix:
然后zip(* l)转置该矩阵:
zip(*l) == [(1, 4),
(2, 5),
(3, 6)]
The *
works like this: some_func(*some_list)
unpacks some_list
so that the function is in effect called with the elements of some_list
as arguments. So zip(*l)
is the same as zip([1, 2, 3], [4, 5, 6])
. Here's the relevant part of the python tutorial.
*的工作方式如下:some_func(* some_list)解包some_list,以便使用some_list的元素作为参数调用该函数。因此zip(* l)与zip([1,2,3],[4,5,6])相同。这是python教程的相关部分。
zip
acts like a zipper, hence the name, so it returns a list with these elements: a tuple of all the first elements of the given arguments, followed by a tuple of all the second elements, etc.
zip就像一个拉链,因此得名,所以它返回一个包含这些元素的列表:给定参数的所有第一个元素的元组,后跟所有第二个元素的元组,等等。
#2
4
Code below will also do the trick:
下面的代码也可以解决问题:
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])
#3
1
[(dat[0], dat[2]) for dat in all_data]
means that you're creating a list of tuples (dat[0],dat[2])
. It does not mean you have two lists, one of d[0]
and the other of d[2]
.
[(dat [0],dat [2])for all_data中的dat]表示您正在创建元组列表(dat [0],dat [2])。这并不意味着你有两个列表,一个是d [0],另一个是d [2]。
You could simply use zip
, but that will result in tuples. If you want lists, you'll have to apply list
to the result:
你可以简单地使用zip,但这将导致元组。如果您需要列表,则必须将列表应用于结果:
(ids, gds) = map(list,zip(*[(dat[0], dat[2]) for dat in a]))
#4
0
Since you are creating two separate lists, try this:
由于您要创建两个单独的列表,请尝试以下操作:
ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data]
or you can unpack it to a single list with the command you used:
或者您可以使用您使用的命令将其解压缩到单个列表:
x = [(dat[0], dat[2]) for dat in all_data]