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

was*_*lli 150 python list

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

[(1, u'abc'), (2, u'def')]
Run Code Online (Sandbox Code Playgroud)

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

[1,2]
Run Code Online (Sandbox Code Playgroud)

我将使用此列表,__in因此它需要是一个整数值列表.

Rak*_*esh 210

>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
Run Code Online (Sandbox Code Playgroud)


Way*_*San 63

使用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]
Run Code Online (Sandbox Code Playgroud)

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

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

>>> print(list(list(zip(*inpt))[0]))
[1, 2]
Run Code Online (Sandbox Code Playgroud)

  • @JuliandotNut 不,它是一个内置函数。(在 Python 2.x 中) (2认同)

mgi*_*son 21

你的意思是这样的吗?

new_list = [ seq[0] for seq in yourlist ]
Run Code Online (Sandbox Code Playgroud)

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

在这里,我创建了一个平面列表,因为这通常比创建1个元素元组的列表更有用.但是,您可以轻松地更换刚刚创造100元的元组的列表seq[0](seq[0],).

  • @wasimbhalli - `int()`在我的解决方案中没有任何地方,所以你看到的异常必须在代码中稍后出现. (4认同)

sso*_*ler 10

你可以使用"tuple unpacking":

>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]
Run Code Online (Sandbox Code Playgroud)

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

>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'
Run Code Online (Sandbox Code Playgroud)


bca*_*tle 7

operator.itemgetter是为了什么.

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

itemgetter语句返回一个函数,该函数返回您指定的元素的索引.它和写作完全一样

>>> b = map(lambda x: x[0], a)
Run Code Online (Sandbox Code Playgroud)

但我发现这itemgetter更清晰,更明确.

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

>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]
Run Code Online (Sandbox Code Playgroud)


rus*_*ro1 7

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

I) 具有 2 个元素的元组的基准 在此处输入图片说明

正如您可能期望通过索引从元组中选择第一个元素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()
Run Code Online (Sandbox Code Playgroud)

II) 具有 2 个或更多元素的元组的基准 在此处输入图片说明

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()
Run Code Online (Sandbox Code Playgroud)


小智 5

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

>>> 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']
>>> 
Run Code Online (Sandbox Code Playgroud)

  • 这将丢失订单。不过,它可能与`ordereddict`一起使用。 (4认同)

bol*_*old 5

从性能的角度来看,在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)
Run Code Online (Sandbox Code Playgroud)

输出

3.491014136001468e-05

3.422205176000717e-05


U10*_*ard 5

我更喜欢这样压缩:

>>> lst = [(1, u'abc'), (2, u'def')]
>>> new, _ = zip(*lst)
>>> new
(1, 2)
>>> 
Run Code Online (Sandbox Code Playgroud)

或者,如果您不知道有多少额外值:

>>> new, *_ = zip(*lst)
>>> new
(1, 2)
>>> 
Run Code Online (Sandbox Code Playgroud)