我有一个元组列表,我只想返回第二列数据,只有唯一值
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
期望的输出:
['Andrew@gmail.com','Jim@gmail.com','Sarah@gmail.com']
我的想法是遍历列表并将第二列中的项追加到新列表中,然后使用以下代码。在我沿着这条路走得太远之前,我知道有更好的方法可以做到这一点。
from collections import Counter
cnt = Counter(mytuple_new)
unique_mytuple_new = [k for k, v in cnt.iteritems() if v > 1]
答案 0 :(得分:3)
您可以使用zip
功能:
>>> set(zip(*mytuple)[1])
set(['Sarah@gmail.com', 'Jim@gmail.com', 'Andrew@gmail.com'])
或者作为性能较低的方式,您可以使用map
和operator.itemgetter
并使用set
来获取唯一元组:
>>> from operator import itemgetter
>>> tuple(set(map(lambda x:itemgetter(1)(x),mytuple)))
('Sarah@gmail.com', 'Jim@gmail.com', 'Andrew@gmail.com')
我的回答:
s = """\
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
set(zip(*mytuple)[1])
"""
print timeit.timeit(stmt=s, number=100000)
0.0740020275116
icodez回答:
s = """\
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
seen = set()
[x[1] for x in mytuple if x[1] not in seen and not seen.add(x[1])]
"""
print timeit.timeit(stmt=s, number=100000)
0.0938332080841
s = """\
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
set([k[1] for k in mytuple])
"""
print timeit.timeit(stmt=s, number=100000)
0.0699651241302
Adem的回答:
s = """
from itertools import izip
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
set(map(lambda x: x[1], mytuple))
"""
print timeit.timeit(stmt=s, number=100000)
0.237300872803 !!!
答案 1 :(得分:1)
尝试:
>>> unique_mytuple_new = set([k[1] for k in mytuple])
>>> unique_mytuple_new
set(['Sarah@gmail.com', 'Jim@gmail.com', 'Andrew@gmail.com'])
答案 2 :(得分:1)
unique_emails = set(item[1] for item in mytuple)
列表推导将帮助您生成仅包含第二列数据的列表,并将该列表转换为set()
可删除重复的值。
答案 3 :(得分:1)
您可以使用列表推导和集合来跟踪看到的值:
>>> mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
>>> seen = set()
>>> [x[1] for x in mytuple if x[1] not in seen and not seen.add(x[1])]
['Andrew@gmail.com', 'Jim@gmail.com', 'Sarah@gmail.com']
>>>
此解决方案最重要的部分是保存订单,就像您的示例一样。只做set(x[1] for x in mytuple)
或类似的东西会获得独特的项目,但他们的订单将丢失。
此外,if x[1] not in seen and not seen.add(x[1])
看起来有点奇怪,但它实际上是一个巧妙的技巧,允许你在列表理解中添加项目(否则,我们需要使用for循环)
由于and
在Python中执行短路评估,not seen.add(x[1])
仅在x[1] not in seen
返回True
时才会被评估。因此,条件是x[1]
是否在集合中,如果没有则添加它。
not
运算符放在seen.add(x[1])
之前,以便条件评估为True
,如果x[1]
需要添加到集合中(set.add
返回{ {1}},被视为None
。False
为not False
)。
答案 4 :(得分:0)
明显简单的循环怎么样?无需创建列表然后转换为设置,只是不添加重复项。
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
result = []
for item in mytuple:
if item[1] not in result:
result.append(item[1])
print result
<强>输出:强>
['Andrew@gmail.com', 'Jim@gmail.com', 'Sarah@gmail.com']
答案 5 :(得分:0)
项目的顺序是否重要?很多建议的答案使用set
来唯一 - 如果列表。如果订单不重要,这是好的,适当的,高效的。如果订单确实很重要,您可以使用OrderedDict
执行类似集合的唯一化,同时保留订单。
# test data
mytuple = [('Andrew','Andrew@gmail.com','20'),('Jim',"Jim@gmail.com",'12'),("Sarah","Sarah@gmail.com",'43'),("Jim","Jim@gmail.com",'15'),("Andrew","Andrew@gmail.com",'56')]
from collections import OrderedDict
emails = list(OrderedDict((t[1], 1) for t in mytuple).keys())
print emails
产量:
['Andrew@gmail.com', 'Jim@gmail.com', 'Sarah@gmail.com']
<强>更新强>
根据iCodez的建议,重申答案:
from collections import OrderedDict
emails = list(OrderedDict.fromkeys(t[1] for t in mytuple).keys())