2017-03-09 33 views
-4

我有元組的列表:名單從列表共享一個值元的所有項目

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)]]

我不知道最後的價值當然。

回答

3

從itertools就可以組一個lambda通過模塊

使用GROUPBY首先用相同的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

然後寫自定義組功能,搜索是通過使用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, []) 

與列表理解

如果創建一個字典,並使用每個元組爲keytuple_tail值,使value爲所有包含該key作爲自己尾巴的元組。然後,您可以使用列表理解積累了字典的值和DIS包括長度的元素小於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)]] 
+0

是否可以在不導入任何額外模塊的情況下執行此操作?最好作爲列表理解? – dyb

+0

@dyb有些想法後,我知道了!一探究竟。 –

0

首先,根據排序去年元素(可以使用this one

然後,他們組。您可以簡單地使用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. 

我還沒有測試,我不確定的語法。

+0

你應該詳細說明如何將它們組合爲一個完整的回答 –

+0

OP也想刪除(x,y,4)。 –

+0

@NoticeMeSenpai,我確信我寫了一個僞代碼,感謝您的反饋。 – smttsp

1

你可以用字典來組項目與同最後一個元素

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)]] 
相關問題