列出共享值的元组列表中的所有项

  • 本文关键字:列表 元组 共享 python
  • 更新时间 :
  • 英文 :


我有一个元组列表:

l = [(x,y,2),(x,y,3),(x,y,4),(x,y,2),(x,y,2),(x,y,3)]

我需要将共享最后一个值的元组提取到元组列表列表中:

nl = [[(x,y,2),(x,y,2),(x,y,2)],[(x,y,3),(x,y,3)]]

我当然不知道最后一个值。

带模块

使用 itertools 中的 groupby,您可以通过首先使用相同的 lambda 进行排序然后分组来对 lambda 进行分组。通过列表理解,您可以将所有分组组合在一起,并过滤掉长度为 1 的所有内容,以摆脱不共享值的元组。

from itertools import groupby
tuples = [(1, 2, 2), (3, 1, 3), (1, 2, 4), (8, 9, 2), (12, 1, 2), (0, 1, 3)]
tuple_tail = lambda (first, mid, last): last
tuples.sort(key=tuple_tail)
print filter(lambda item: len(item) > 1, [list(group) for key, group in groupby(tuples, tuple_tail)])

不带模块

所以这个不是最好的解决方案,但它是一个解决方案。我定义了一些帮助程序函数

  1. retrieves last of tuple
  2. compares equality of two tuples.

然后编写了一个自定义 group 函数,该函数使用filter搜索所有相等的元素,然后在所有元素中map该元素,以获取包含所有可能分组的列表(全部分组)。我想不出一种在不弄乱的情况下使用列表理解的方法,所以我选择了reduce并编写了一个函数来删除重复和/或长度为 1(fn)的元素。如果您使用set或者只是一般不同的方法,这肯定可以优化。希望这可以帮助您找到该方法。

tuples = [(1, 2, 2), (3, 1, 3), (1, 2, 4), (8, 9, 2), (12, 1, 2), (0, 1, 3)]
# helper functions
tuple_tail = lambda (first, mid, last): last
is_tuples_equal = lambda tuple1, tuple2: tuple_tail(
tuple1) == tuple_tail(tuple2)
# groups by last (_,_,last)
group_by_last = lambda tuple: filter(
lambda item: is_tuples_equal(item, tuple), tuples)
# get all groupings
group_all = map(group_by_last, tuples)
# if group is not in list and not length of 1 insert into list
fn = lambda acc, val: acc if val in acc or len(val) == 1 else acc + [val]
print reduce(fn, group_all, [])

使用列表理解

如果创建一个字典并使用每个元组的tuple_tail值作为key,并将value作为包含该key的所有元组作为其尾部。然后,您可以使用列表推导来累积字典的值,并包含长度小于 1 的元素。

tuples = [(1, 2, 2), (3, 1, 3), (1, 2, 4), (8, 9, 2), (12, 1, 2), (0, 1, 3)]
mydict = dict()
create = lambda tupl: mydict.update({tuple_tail(tupl): [tupl]})
update = lambda tupl: mydict[tuple_tail(tupl)].append(tupl)
tuple_tail = lambda (first, mid, last): last
populate = lambda tupl: update(tupl) if tuple_tail(tupl) in mydict else create(tupl)
map(populate, tuples)
print [tuple for tuple in mydict.values() if len(tuple) > 1]

最终结果

[[(1, 2, 2), (8, 9, 2), (12, 1, 2)], [(3, 1, 3), (0, 1, 3)]]

您可以使用dict 对具有相同最后一个元素的项目进行分组

x,y= 'x','y'
l = [(x,y,2),(x,y,3),(x,y,4),(x,y,2),(x,y,2),(x,y,3)]
res = {}
for item in l:
if item[2] not in res:
res[item[2]] = []
res[item[2]].append(list(item))
print filter( lambda x: len(x) > 1 , res.values())
[['x', 'y', 2], ['x', 'y', 2], ['x', 'y', 2]], [['x', 'y', 3], ['x', 'y', 3]]

或使用熊猫

l = pd.Series( [(x,y,2),(x,y,3),(x,y,4),(x,y,2),(x,y,2),(x,y,3) ])
print [ line[1].tolist() for line in l.groupby( lambda x: l[x][2] ) if len(line[1]) > 1]
[[('x', 'y', 2), ('x', 'y', 2), ('x', 'y', 2)], [('x', 'y', 3), ('x', 'y', 3)]]

首先,根据最后一个元素排序(你可以使用这个)

然后,对它们进行分组。您可以简单地使用for loop.伪代码是:

cur_value = list[0][2] #second element of first tuple
llt = []; #list_of_list_of_tuples
for tuple in list:
l_tpl = []
if cur_value == tuple[2]:
l_tpl.append(tuple)
else:
if len(l_tpl) > 1:
llt.append(l_tpl)
if len(l_tpl) > 1:
llt.append(l_tpl)  # we need to add the last list of tuples. 

我还没有测试过,也不确定语法。

最新更新