我有一个如下所示的列表,其中第一个元素是id,另一个是字符串:
[(1, u'abc'), (2, u'def')]
我想只从这个元组列表中创建一个id列表,如下所示:
[1,2]
我将使用此列表,__in因此它需要是一个整数值列表.
Rak*_*esh 210
>>> a = [(1, u'abc'), (2, u'def')]
>>> [i[0] for i in a]
[1, 2]
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]
编辑(@BradSolomon):以上适用于Python 2.x,zip返回列表.
在Python 3.x中,zip返回一个迭代器,以下内容等同于上面的内容:
>>> print(list(list(zip(*inpt))[0]))
[1, 2]
mgi*_*son 21
你的意思是这样的吗?
new_list = [ seq[0] for seq in yourlist ]
你实际拥有的是一个tuple对象列表,而不是一个集合列表(正如你原来的问题所暗示的那样).如果它实际上是一个集合列表,则没有第一个元素,因为集合没有顺序.
在这里,我创建了一个平面列表,因为这通常比创建1个元素元组的列表更有用.但是,您可以轻松地更换刚刚创造100元的元组的列表seq[0]与(seq[0],).
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]
在迭代时,每个元组都被解包,其值被设置为变量idx和val.
>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'
这operator.itemgetter是为了什么.
>>> 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)
但我发现这itemgetter更清晰,更明确.
这对于生成紧凑的排序语句很方便.例如,
>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]
我认为比较不同方法的运行时间可能会很有用,所以我做了一个基准测试(使用simple_benchmark库)
正如您可能期望通过索引从元组中选择第一个元素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()
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()
小智 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']
>>> 
从性能的角度来看,在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
我更喜欢这样压缩:
>>> lst = [(1, u'abc'), (2, u'def')]
>>> new, _ = zip(*lst)
>>> new
(1, 2)
>>> 
或者,如果您不知道有多少额外值:
>>> new, *_ = zip(*lst)
>>> new
(1, 2)
>>> 
| 归档时间: | 
 | 
| 查看次数: | 186003 次 | 
| 最近记录: |