我需要从元组列表中生成一个列表:
a = [(1,2), (1,3), (2,3), (2,5), (2,6), (3,4), (3,6), (4,7), (5 6), (5,9), (5,10), (6,7)
(6.10) (6.11) (7.8) (7.12) (8.12) (9.10) (10.11)]
规则是:
- 我有任何记录(begin = random.choice (a)
)
- 新列表中的项目必须具有以下关系:
列表中每个元组的最后一项必须等于要插入的下一个元组的第一项。
有效输出的示例(从元组(3.1)开始):
[(3, 1), (1, 2), (2, 3), (3, 4), (4, 7), (7, 8), (8, 12), (12, 7), (7, 6), (6, 2), (2, 5), (5, 6), (6, 10), (10, 5) (5, 9), (9, 10), (10, 11), (11, 6), (6, 3)]
我该怎么做?它使用列表理解吗? 谢谢!
答案 0 :(得分:0)
在这里,lisb
将按照您寻找的顺序填充元组。当然,如果lisa
提供了适当的元组(即,每个元组具有与另一个元组的第0个值匹配的第1个值)。无论实现如何,您的样本列表都不起作用,因为所有值都不匹配(例如,没有第12个元素,因此元组不能连接到任何其他元组)...所以你应该想出一个更好的样本列表。
经过测试,正常工作。
import random
lisa = [(1, 2), (3, 4), (2, 3), (4, 0), (0, 9), (9, 1)]
lisb = []
current = random.choice(lisa)
while True:
lisa.remove(current)
lisb.append(current)
current = next((y for y in lisa if y[0] == current[1]), None)
if current == None:
break
print lisb
如果您不想从lisa
删除项目,只需切片新列表。
答案 1 :(得分:0)
作为生成器功能:
def chained_tuples(x):
oldlist = x[::]
item = random.choice(oldlist)
oldlist.remove(item)
yield item
while oldlist:
item = next(next_item for next_item in oldlist if next_item[0] == item[1])
oldlist.remove(item)
yield item
如上所述,如果您的列表实际上并不是可链接的,那么您将得到一个不完整的回复,例如您的示例列表。
答案 2 :(得分:0)
我认为到目前为止所有答案都缺少要求(至少根据您的示例输出)找到最长链。
我建议的解决方案是递归解析所有可能构造的链,并返回最长的结果。该函数如下所示:
def generateTuples(list, offset, value = None):
if value == None: value = list[offset]
list = list[:offset]+list[offset+1:]
res = []
for i,(a,b) in enumerate(list):
if value[1] in (a,b):
if value[1] == a:
subres = generateTuples(list, i, (a,b))
else:
subres = generateTuples(list, i, (b,a))
if len(subres) > len(res):
res = subres
return [value] + res
你会这样称呼它:
results = generateTuples(a, 1, (3,1))
制作清单:
[(3, 1), (1, 2), (2, 3), (3, 4), (4, 7), (7, 8), (8, 12), (12, 7), (7, 6),
(6, 2), (2, 5), (5, 6), (6, 10), (10, 5), (5, 9), (9, 10), (10, 11),
(11, 6), (6, 3)]
该函数的第一个参数是元组的源列表,第二个参数是要使用的第一个元素的偏移量,第三个参数是可选的,但允许您覆盖第一个元素的值。当您想要以与您的示例中相反的顺序开始使用元组时,后者非常有用。
答案 3 :(得分:0)
只是添加解决此问题的另一种方法:
import random
from collections import defaultdict
lisa = [(1, 2), (3, 4), (2, 3), (4, 0), (0, 9), (9, 1)]
current_start, current_end = lisa[random.randint(0, len(lisa) - 1)]
starts = defaultdict(list)
lisb = [(current_start, current_end)]
for start, end in lisa:
starts[start].append(end)
while True:
if not starts[current_end]:
break
current_start, current_end = current_end, starts[current_end].pop()
lisb.append((current_start, current_end))
注意:您必须确保lisa
不为空。