這樣的事情,使用unique_everseen
從itertools recipes和chain()
:
In [26]: from itertools import *
In [27]: lis1=[["NO","Norge"],["SE","Sverige"],["GR","Hellas"]]
In [28]: lis2=[["NO","Norway"],["SE","Sweden"],["GR","Greece"]]
In [29]: from itertools import *
In [30]: def unique_everseen(iterable, key=None):
seen = set()
seen_add = seen.add
if key is None:
for element in ifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
....:
In [31]: [list(unique_everseen(chain(*x))) for x in izip(lis1,lis2)]
Out[31]:
[['NO', 'Norge', 'Norway'],
['SE', 'Sverige', 'Sweden'],
['GR', 'Hellas', 'Greece']]
或:可以使用groupby
從itertools,與operator.itemgetter()
結合:
In [42]: from operator import *
In [43]: [[k]+list(map(itemgetter(1),g)) for x in zip(lis1,lis2) for k,g in groupby(x,itemgetter(0))]
Out[43]:
[['NO', 'Norge', 'Norway'],
['SE', 'Sverige', 'Sweden'],
['GR', 'Hellas', 'Greece']]
或使用collections.OrderedDict
,這是dict
的子類別並維護順序:
In [47]: from collections import OrderedDict
In [48]: dic=OrderedDict()
In [49]: for x in lis1:
....: dic.setdefault(x[0],[]).append(x[1])
....:
In [50]: for x in lis2:
dic.setdefault(x[0],[]).append(x[1])
....:
In [51]: dic
Out[51]: OrderedDict([('NO', ['Norge', 'Norway']), ('SE', ['Sverige', 'Sweden']), ('GR', ['Hellas', 'Greece'])])
In [52]: [[x]+y for x,y in dic.items()]
Out[52]:
[['NO', 'Norge', 'Norway'],
['SE', 'Sverige', 'Sweden'],
['GR', 'Hellas', 'Greece']]
#or directly access the names using the short-name
In [53]: dic['NO']
Out[53]: ['Norge', 'Norway']
In [54]: dic['GR']
Out[54]: ['Hellas', 'Greece']
請注意,這個答案和Ashwini的答案在涉及允許的輸入和結果輸出時有兩個區別:即使國家/地區的順序在列表之間不同,但此方案(自然地)也不保留此順序解決方案。 –
謝謝!非常乾淨,簡短的代碼和易於理解:) –
@lazyr增加了一個解決方案,即使列表是隨機排列的,也保留了順序。 –