我需要以一种特定的方式排列我的列表-python

我需要以一种特定的方式排列我的列表-python,python,list,function,math,list-comprehension,Python,List,Function,Math,List Comprehension,基本上,用户输入任何正数,然后程序应该安排一个列表,其中包含所有正数,直到输入的数字,这样列表中两个连续元素的总和就是一个平方数。如果输入的数字不允许排序,我只希望程序打印错误。这是迄今为止的代码: u = int(input("ENTER: ")) l = [] for i in range(1, u + 1): l.append(i) o = l t = [] for elem in l: for x in o: p = elem + x p

基本上,用户输入任何正数,然后程序应该安排一个列表,其中包含所有正数,直到输入的数字,这样列表中两个连续元素的总和就是一个平方数。如果输入的数字不允许排序,我只希望程序打印错误。这是迄今为止的代码:

u = int(input("ENTER: "))
l = []
for i in range(1, u + 1):
    l.append(i)
o = l
t = []
for elem in l:
    for x in o:
        p = elem + x
        p = math.sqrt(p)
        if p%1 == 0:
            if x == elem:
                break
            else:
                t.append(x)
                t.append(elem)
例如,如果我输入15,则列表t最后如下所示:

[3, 1, 8, 1, 15, 1, 1, 3, 6, 3, 13, 3, 5, 4, 12, 4, 4, 5, 11, 5, 3, 6, 10, 6, 2, 7, 9, 7, 1, 8, 7, 9, 6, 10, 15, 10, 5, 11, 14, 11, 4, 12, 13, 12, 3, 13, 12, 13, 2, 14, 11, 14, 1, 15, 10, 15]
这个列表包含了理论上可以工作的所有对,我一直在安排这个列表,以便每个数字出现一次,并且每个连续的数字都遵循上面提到的属性

所以我最后要找的名单是:

[8, 1, 15, 10, 6, 3, 13, 12, 4, 5, 11, 14, 2, 7, 9]

提前感谢您提供的任何帮助。

当您使用两个for循环时,您通常会将相同的数字添加到彼此,而不是列表中的下一个 (l中的elem==o中的x)始终为真

当你使用(p%1==0)时,另一个总是正确的

要删除重复项,请更正您的代码,然后您可以轻松地将列表转换为如下所示的集合:

NoDuplicatedList=set(t)

t是要从中删除重复项的列表


但是,您可能会丢失列表的顺序。

这将是一种使用递归函数的蛮力方法:

import math

def f(temp, numbers):
    for i, j in zip(temp[:-1], temp[1:]):
        sqrt = math.sqrt(i+j)
        if int(sqrt) != sqrt:
            return False
    if not numbers:
        return temp
    for i in numbers:
        result = f(temp + [i], [j for j in numbers if j != i])
        if result:
            break
    return result

n = int(input("Arrange numbers from 1 to ").strip())
numbers = list(range(1, n+1))
print("Input:", numbers)
print("Output:", f([], numbers))
示例4:

Arrange numbers from 1 to 4
Input: [1, 2, 3, 4]
Output: False
示例15:

Arrange numbers from 1 to 15
Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Output: [8, 1, 15, 10, 6, 3, 13, 12, 4, 5, 11, 14, 2, 7, 9]

你快到了。您可以使用图形完成最后的步骤。列表t最好作为表示边的元组对

您也可以在以后修改列表,如下所示

t =[3, 1, 8, 1, 15, 1, 1, 3, 6, 3, 13, 3, 5, 4, 12, 4, 4, 5, 11, 5, 3, 6, 10, 6, 2, 7, 9, 7, 1, 8, 7, 9, 6, 10, 15, 10, 5, 11, 14, 11, 4, 12, 13, 12, 3, 13, 12, 13, 2, 14, 11, 14, 1, 15, 10, 15]
t = list(zip(t[::2],t[1::2]))
我建议您稍微修改一下原始代码

import networkx as nx
import math

u = int(input("ENTER: "))
l = []
for i in range(1, u + 1):
    l.append(i)
o = l
t = []
for elem in l:
    for x in o:
        p = elem + x
        p = math.sqrt(p)
        if p%1 == 0:
            if x == elem:
                break
            else:
                t.append((x, elem)) #to keep tuples instead
现在,把它变成一个图问题。递归查找所有邻居,直到获得最大长度。跟踪您已经访问过的邻居,以避免再次穿越相同的路径

G = nx.Graph()
G.add_edges_from(t)
#Now, you need to find "new" neighbours for all possible combinations that make the longest chain in your case
def findPaths(G, current_node, n, to_exclude = None):
    if to_exclude == None:
        to_exclude = set([current_node])
    else:
        to_exclude.add(current_node)
    if n==1:
        return [[current_node]]
    paths = [[current_node]+path for neighbor in G.neighbors(current_node) if neighbor not in to_exclude for path in findPaths(G,neighbor,n-1,to_exclude)]
    to_exclude.remove(current_node)
    return paths


allpaths = []
for node in G:
    allpaths.extend(findPaths(G, node, G.number_of_nodes()))
if allpaths:
    print('match found')
    [print(x) for x in allpaths]
else:
    print('no matches')

我将对@jayyyy的答案做一些轻微的改进。这段代码在@jayyyy的基础上稍作修改,稍微复杂一些,但速度也更快。对于
n=15
而言,此代码在我的系统上快7.5倍以上,对于
n=30
而言快19倍以上。通过减少总和为平方数的检查次数并加快检查速度,可以提高速度。我还移动了平方数检查,以减少例行调用本身的次数

最后,我更改了一些变量名,使其更易于自我记录。但是@jayjayy的代码仍然非常简单,值得称赞

import math

def f(listsofar, numbersleft):
    if not numbersleft:
        return listsofar
    result = False
    for i in numbersleft:
        if not listsofar or math.sqrt(listsofar[-1] + i).is_integer():
            result = f(listsofar + [i], [j for j in numbersleft if j != i])
            if result:
                break
    return result

n = int(input("Arrange numbers from 1 to ").strip())
numbers = list(range(1, n+1))
print("Input:", numbers)
print("Output:", f([], numbers))

你懂图论或路径搜索吗?您成功地找到了数字之间的所有连接——现在您需要找到使用这些连接的“最大路径”。搜索并了解这些主题。感谢您接受我的答案,但我觉得这样做不对。我的回答基于Jayyyy的回答:主要思想是他(或她的),而我的改变提高了速度,但仍然相对较小。他鼓励我仔细研究这个问题,我的目的是回馈社会,而不是从他身上夺走。我以前也解决过类似的问题,但他的方法比我的好。请接受他的答案,而不是我的。@Jayjayyy这行是做什么的:对于zip中的i,j(temp[:-1],temp[1:]):