如何获取元组列表中的第一个元素?

时间:2012-08-27 12:38:37

标签: python list

我有一个如下所示的列表,其中第一个元素是id,另一个是字符串:

[(1, u'abc'), (2, u'def')]

我想只从这个元组列表中创建一个id列表,如下所示:

[1,2]

我将在__in中使用此列表,因此它必须是整数值列表。

13 个答案:

答案 0 :(得分:178)

>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]

答案 1 :(得分:56)

使用zip功能解耦元素:

>>> inpt = [(1, u'abc'), (2, u'def')]
>>> unzipped = zip(*inpt)
>>> print unzipped
[(1, 2), (u'abc', u'def')]
>>> print list(unzipped[0])
[1, 2]

编辑(@ BradSolomon): 以上适用于Python 2.x,其中zip返回一个列表。

在Python 3.x中,zip返回一个迭代器,以下内容等同于上述内容:

>>> print(list(list(zip(*inpt))[0]))
[1, 2]

答案 2 :(得分:18)

你是说这样的意思吗?

new_list = [ seq[0] for seq in yourlist ]

您实际拥有的是tuple个对象列表,而不是集合列表(正如您的原始问题所暗示的那样)。如果它实际上是一个集合列表,则没有第一个元素,因为集合没有订单。

这里我创建了一个平面列表,因为这通常比创建1个元素元组的列表更有用。但是,只需将seq[0]替换为(seq[0],),即可轻松创建1个元素元组的列表。

答案 3 :(得分:7)

您可以使用" tuple unpacking":

>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]

在迭代时,每个元组都被解压缩,其值被设置为变量idxval

>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'

答案 4 :(得分:5)

这是operator.itemgetter的用途。

var data = {
	'Category xxxx': [
	{ units: 1234, subcategory: 'wolves', name: 'Starks' }, 
	{ units: 1345354, subcategory: 'wolves', name: 'Starks' }, 
	{ units: 666, subcategory: 'dragons', name: 'Targaryens' }
	],
	'Category yyyy': [
	{ units: 7783, subcategory: 'lions', name: 'Lanisters' }, 
	{ units: 1267878, subcategory: 'spires', name: 'Martells' }
	]
};

var result = {};

Object.keys(data).forEach(function (key) {
	var hash = {};
	data[key].forEach(function (v, k) {
		isNaN(hash[(k = v.subcategory + v.name)]) ?
			(hash[k] = this.push(v) - 1) :
			(this[hash[k]].units += v.units);
	}, (this[key] = []));
}, result);

console.log(result)

>>> a = [(1, u'abc'), (2, u'def')] >>> import operator >>> b = map(operator.itemgetter(0), a) >>> b [1, 2] 语句返回一个函数,它返回您指定的元素的索引。这和写作完全一样

itemgetter

但我发现>>> b = map(lambda x: x[0], a) 更清晰,more explicit

这对于生成紧凑的排序语句很方便。例如,

itemgetter

答案 5 :(得分:5)

我当时认为比较不同方法的运行时可能有用,所以我做了一个基准测试(使用simple_benchmark库)

I)具有包含2个元素的元组的基准 enter image description here

您可能希望通过索引0从元组中选择第一个元素,这显示出是最快的解决方案,非常接近拆包解决方案,因为它恰好需要2个值

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()



@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_function()
def ssoler_upacking(l):
    return [idx for idx, val in l]

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]



@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [(random.choice(range(100)), random.choice(range(100))) for _ in range(size)]


r = b.run()
r.plot()

II)具有包含2个或更多元素的元组的基准 enter image description here

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]


@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [tuple(random.choice(range(100)) for _
                     in range(random.choice(range(2, 100)))) for _ in range(size)]

from pylab import rcParams
rcParams['figure.figsize'] = 12, 7

r = b.run()
r.plot()

答案 6 :(得分:4)

如果元组是唯一的,那么这可以工作

>>> a = [(1, u'abc'), (2, u'def')]
>>> a
[(1, u'abc'), (2, u'def')]
>>> dict(a).keys()
[1, 2]
>>> dict(a).values()
[u'abc', u'def']
>>> 

答案 7 :(得分:4)

从性能的角度来看,在python3.X

  • [i[0] for i in a]list(zip(*a))[0]相同
  • 它们比list(map(operator.itemgetter(0), a))

<强>代码

import timeit


iterations = 100000
init_time = timeit.timeit('''a = [(i, u'abc') for i in range(1000)]''', number=iterations)/iterations
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = [i[0] for i in a]''', number=iterations)/iterations - init_time)
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = list(zip(*a))[0]''', number=iterations)/iterations - init_time)

<强>输出

3.491014136001468e-05

3.422205176000717e-05

答案 8 :(得分:1)

当我跑步时(如上所述):

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b

而不是返回:

[1, 2]

我收到了这个作为回报:

<map at 0xb387eb8>

我发现我必须使用list():

>>> b = list(map(operator.itemgetter(0), a))

使用此建议成功返回列表。也就是说,我对这个解决方案很满意,谢谢。 (使用Spyder,iPython控制台,Python v3.6测试/运行)

答案 9 :(得分:1)

我想知道为什么没人建议使用numpy,但是现在检查后我明白了。对于混合类型数组,可能不是最好的方法。

这将是numpy中的解决方案:

>>> import numpy as np

>>> a = np.asarray([(1, u'abc'), (2, u'def')])
>>> a[:, 0].astype(int).tolist()
[1, 2]

答案 10 :(得分:0)

那些是元组,而不是集合。你可以这样做:

l1 = [(1, u'abc'), (2, u'def')]
l2 = [(tup[0],) for tup in l1]
l2
>>> [(1,), (2,)]

答案 11 :(得分:0)

您可以unpack使用元组列表理解元组并仅获取第一个元素:

l = [(1, u'abc'), (2, u'def')]
[f for f, *_ in l]

输出:

[1, 2]

无论元组中有多少个元素,这都将起作用:

l = [(1, u'abc'), (2, u'def', 2, 4, 5, 6, 7)]
[f for f, *_ in l]

输出:

[1, 2]

答案 12 :(得分:0)

要获取列表或元组的元素,您可以遍历列表或元组

a = [(1, u'abc'), (2, u'def')]

list1 = [a[i][0] for i in range(len(a))]

print(list1)