如何根据原始元组列表中的值创建新的元组列表?
How to create a new list of tuples based on a values from original list of tuples?
我的函数当前正在返回:
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
但是,我需要最终输出为:
[('a', 'h'), ('d', 'g')]
如您所见,如果 i[1] 和 i[2] 匹配,我需要将 i[0] 配对在一起。
我正在尝试使用 for 循环,但此时此刻我想不出如何编写它。
根据每个元组的第二个和第三个元素进行分组,将第一个元素附加到列表中,然后过滤掉长度<1的列表:
from collections import defaultdict
d = defaultdict(list)
for a,b,c in l:
d[b,c].append(a)
print([tuple(val) for val in d.values() if len(val)>1])
[('a', 'h'), ('d', 'g')]
要保证第一个匹配顺序,请使用 OrderedDict:
from collections import OrderedDict
d = OrderedDict()
for a,b,c in l:
d.setdefault((b,c),[]).append(a)
print([tuple(val) for val in d.values() if len(val)>1])
您可以根据第二个和第三个元素对列表进行排序,然后使用 itertools.groupby
来完成此操作。然后对于每个组,您可以从其中的元素中取出第一个元素。例子-
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> lst = []
>>> new_a = sorted(a, key=lambda i: (i[1], i[2]))
>>> for _, x in itertools.groupby(new_a, lambda i: (i[1], i[2])):
... lst.append(tuple(y[0] for y in x))
...
>>> lst
[('a', 'h'), ('d', 'g')]
这也可以在一行中完成(虽然不可读)-
>>> l = [tuple(y[0] for y in x) for _, x in itertools.groupby(sorted(a, key=lambda i: (i[1], i[2])), lambda i: (i[1], i[2]))]
>>> l
[('a', 'h'), ('d', 'g')]
我认为此解决方案将保留顺序(基于初始匹配位置):
from itertools import groupby
from operator import itemgetter
from collections import defaultdict
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings, seen_list=defaultdict(list), []
for key, value in groupby(x, itemgetter(1, 2)):
if key not in seen_list:
seen_list.append(key)
groupings[key].extend(list(map(itemgetter(0),value)))
print([groupings[key] for key in seen_list])
如果顺序不重要,您可以忽略 seen_list,只打印 groupings.values()
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings=defaultdict(list)
for key, value in groupby(x, itemgetter(1, 2)):
groupings[key].extend(list(map(itemgetter(0),value)))
print(groupings.values())
可能不是那么 pythonic,但更容易一些:
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> c = {}
>>> [c[j+k].append(i) if j+k in c else c.update({j+k:[i]}) for i,j,k in a]
>>> c = c.values()
>>> print c
[['d', 'g'], ['a', 'h']]
这似乎有效:
from itertools import combinations
l = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
print([(a[0], b[0]) for a, b in combinations(l, 2) if a[1:] == b[1:]])
我的函数当前正在返回:
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
但是,我需要最终输出为:
[('a', 'h'), ('d', 'g')]
如您所见,如果 i[1] 和 i[2] 匹配,我需要将 i[0] 配对在一起。
我正在尝试使用 for 循环,但此时此刻我想不出如何编写它。
根据每个元组的第二个和第三个元素进行分组,将第一个元素附加到列表中,然后过滤掉长度<1的列表:
from collections import defaultdict
d = defaultdict(list)
for a,b,c in l:
d[b,c].append(a)
print([tuple(val) for val in d.values() if len(val)>1])
[('a', 'h'), ('d', 'g')]
要保证第一个匹配顺序,请使用 OrderedDict:
from collections import OrderedDict
d = OrderedDict()
for a,b,c in l:
d.setdefault((b,c),[]).append(a)
print([tuple(val) for val in d.values() if len(val)>1])
您可以根据第二个和第三个元素对列表进行排序,然后使用 itertools.groupby
来完成此操作。然后对于每个组,您可以从其中的元素中取出第一个元素。例子-
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> lst = []
>>> new_a = sorted(a, key=lambda i: (i[1], i[2]))
>>> for _, x in itertools.groupby(new_a, lambda i: (i[1], i[2])):
... lst.append(tuple(y[0] for y in x))
...
>>> lst
[('a', 'h'), ('d', 'g')]
这也可以在一行中完成(虽然不可读)-
>>> l = [tuple(y[0] for y in x) for _, x in itertools.groupby(sorted(a, key=lambda i: (i[1], i[2])), lambda i: (i[1], i[2]))]
>>> l
[('a', 'h'), ('d', 'g')]
我认为此解决方案将保留顺序(基于初始匹配位置):
from itertools import groupby
from operator import itemgetter
from collections import defaultdict
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings, seen_list=defaultdict(list), []
for key, value in groupby(x, itemgetter(1, 2)):
if key not in seen_list:
seen_list.append(key)
groupings[key].extend(list(map(itemgetter(0),value)))
print([groupings[key] for key in seen_list])
如果顺序不重要,您可以忽略 seen_list,只打印 groupings.values()
x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
groupings=defaultdict(list)
for key, value in groupby(x, itemgetter(1, 2)):
groupings[key].extend(list(map(itemgetter(0),value)))
print(groupings.values())
可能不是那么 pythonic,但更容易一些:
>>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
>>> c = {}
>>> [c[j+k].append(i) if j+k in c else c.update({j+k:[i]}) for i,j,k in a]
>>> c = c.values()
>>> print c
[['d', 'g'], ['a', 'h']]
这似乎有效:
from itertools import combinations
l = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
print([(a[0], b[0]) for a, b in combinations(l, 2) if a[1:] == b[1:]])