Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将配对列表转换为与第一个共享最后一项的配对列表,或反之亦然_Python_Tuples - Fatal编程技术网

Python 将配对列表转换为与第一个共享最后一项的配对列表,或反之亦然

Python 将配对列表转换为与第一个共享最后一项的配对列表,或反之亦然,python,tuples,Python,Tuples,我有一个元组列表,比如li=[('aa','bb'),('bb','cc'),('dd','ee')]。从li我想生成一个元组对列表,其中li中一个元组的第一个元素等于li中另一个元素的第二个元素。在这里的示例中,输出列表将是一个包含一对元组的列表: [(('aa', 'bb'), ('bb', 'cc'))] 这对于简短的li列表来说非常简单。例如,我做过这样的事情 joints = [] for pair in itertools.permutations(li, r=2): if

我有一个元组列表,比如
li=[('aa','bb'),('bb','cc'),('dd','ee')]
。从
li
我想生成一个元组对列表,其中
li
中一个元组的第一个元素等于
li
中另一个元素的第二个元素。在这里的示例中,输出列表将是一个包含一对元组的列表:

[(('aa', 'bb'), ('bb', 'cc'))]
这对于简短的
li
列表来说非常简单。例如,我做过这样的事情

joints = []
for pair in itertools.permutations(li, r=2):
    if pair[0][1] == pair[1][0]:
        joints += ((pair[0][0], pair[0][1]), (pair[1][0], pair[1][1]))
但是,对于长列表
li
而言,所有长度为2的排列的总数会迅速爆炸,变得难以管理


我认为必须有一个更可行的方法来做到这一点,也许使用矩阵乘法或哈希表。对于较长(例如5000+长度)的列表,如何合理地执行此操作?

维护两个集合-第一个索引中的元素和第二个索引中的元素。从原始列表中,仅附加至少一个元素在两个集合中的元组

li = [('aa', 'bb'), ('bb','cc'), ('dd', 'ee')]

first_pos = {x for x, y in li}
second_pos = {y for x, y in li}

arr = [(x, y) for x, y in li if (x in first_pos and x in second_pos) or (y in
    first_pos and y in second_pos)]

print(arr)
输出-

[('aa', 'bb'), ('bb', 'cc')]

您可以使用字典来收集所需的对。作为一种更具python风格的方法,您可以使用
collections
模块中的
defaultdict()
deque
函数,以便为
deque
中的每一对保留相关对:

>>> from collections import defaultdict, deque
>>> d = defaultdict(deque)

>>> for i, j in li:
...     for k, t in li:
...        if (i, j) != (k, t) and (i == t or j == k):
...             d[(i, j)].append((k, t))
... 
>>> 
>>> d
defaultdict(<type 'collections.deque'>,
            {('dd', 'ee'): deque([('ee', 'mm')]),
             ('rr', 'cc'): deque([('cc', 'tt')]),
             ('cc', 'tt'): deque([('bb', 'cc'), ('rr', 'cc')]),
             ('aa', 'bb'): deque([('bb', 'cc')]),
             ('ee', 'mm'): deque([('dd', 'ee')]),
             ('bb', 'cc'): deque([('aa', 'bb'), ('cc', 'tt')])})
请注意,如果您不想对结果执行任何额外的操作,但如果您想对结果执行更多的操作,如弹出、两侧追加、旋转、,等。
deque
是一个不错的选择,因为它为大多数操作提供了固定的顺序

通过
itertools.permutations
实现更简洁的方式:

>>> from itertools import permutations
>>> for i, j permutations(li, 2):
...        if (i == t or j == k):
...             d[(i, j)].append((k, t))

“拓扑排序”重复的情况如何,元组可以在两种情况下匹配?@Kasramvd在
li
中没有重复项,但是每个元素可以与许多其他元素匹配。谢谢,这非常好。如果我理解你的意思,我想我想要的条件实际上是
j==k
而不是
(I==t或j==k)
。我希望顺序是有意义的:从
[('a,'b'),('b','c')]
我想产生
('a','b'),('b','c'))
,但不是
('b','c'),('a','b'))
@hatshepsu如果你的问题含糊不清,请根据你的需要随意修改;-)。
>>> from itertools import permutations
>>> for i, j permutations(li, 2):
...        if (i == t or j == k):
...             d[(i, j)].append((k, t))