我需要以特定方式排列清单-python

时间:2018-12-09 10:12:02

标签: python list function math list-comprehension

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

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]

在此先感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

这将是一种具有递归功能的蛮力方法:

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]

答案 1 :(得分:2)

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

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

for line_num, sentence in enumerate(wordmatrix):
    dic1[line_num] = {}
    for word in sentence:
        dic1[line_num][word] = dic2[word]

我建议您稍微修改一下原始代码。

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

答案 2 :(得分:2)

我将对@Jayjayyy的答案进行一些细微的改进。这段代码在@Jayjayyy的基础上进行了稍微的修改,虽然稍微复杂一些,但速度也更快。对于select `ep`.`id`, `ep`.`title`, `ep`.`slug`, `ep`.`status`, `ep`.`active`,`ep`.`visitor_id`,`ep`.`type`, `friends`.`customername`, `ep`.`created_at`, epblock.reference_id from enr_posts as ep JOIN (SELECT (CASE WHEN u2.id = 3 THEN u1.name ELSE u2.name END ) as customername, (CASE WHEN u2.id = 3 THEN u1.id ELSE u2.id END ) as customer_id, fr.status FROM enr_friend_requests fr JOIN enr_customers u1 ON fr.sent_by=u1.id JOIN enr_customers u2 ON fr.received_by=u2.id where (fr.sent_by=3 or fr.received_by=3) AND fr.status="accepted") as friends ON ep.visitor_id=friends.customer_id LEFT JOIN enr_post_customer_block as epblock ON `ep`.`id` = epblock.reference_id AND epblock.customer_id=3 WHERE `ep`.`active`=1 AND `ep`.`status`=1 AND epblock.reference_id IS NULL ORDER BY `ep`.`id` DESC ,此代码在我的系统上的速度快7.5倍以上;对于if (centerLatLng != null) { Geocoder geocoder = new Geocoder(CNM_MapsActivity.this, Locale.getDefault()); currentLongitude=centerLatLng.longitude; currentLatitude=centerLatLng.latitude; List<android.location.Address> addresses = new ArrayList<Address>(); try { addresses = geocoder.getFromLocation(centerLatLng.latitude, centerLatLng.longitude, 1); } catch (IOException e) { e.printStackTrace(); } if (addresses != null && addresses.size() > 0) { sdt=addresses.get(0).getAdminArea(); csdt=addresses.get(0).getLocality(); //toolbar.setTitle(csdt); tyssy=addresses.get(0).getPremises();//addresses.get(0).getPremises(); String addresl=addresses.get(0).getAddressLine(0); String ftrn=addresses.get(0).getFeatureName(); String sblc=addresses.get(0).getSubLocality(); String sbna=addresses.get(0).getSubAdminArea(); ttls.setText(csdt); // if(Character.isDigit(addresses.get(0).getAddressLine(0).charAt(0))){ // tyssy ="Prem Nagar"; //addresses.get(0).getAddressLine(1); // } // else if(addresses.get(0).getAddressLine(0).startsWith("Lane")){ // tyssy ="Prem Nagar"; // addresses.get(0).getAddressLine(1); // } // else { // tyssy ="Prem Nagar"; // addresses.get(0).getAddressLine(0); // } // mLocationTextView.setText("Click To Set Your Location"); // progressDialog.dismiss(); // txtLocationAddress.setText(String.valueOf(centerLatLng.latitude)+ // String.valueOf(centerLatLng.longitude)); txtLocationAddress.setText(addresl); // Toast.makeText(MN_MapsActivity.this,"State : "+sdt+"\n"+"city : "+csdt+"\n"+"Premises : "+String.valueOf(tyssy)+"addrs :" +addresl+"\n"+"sblc :"+sblc+"\n"+"featy : "+ ftrn+"\n"+"subadm : "+sbna,Toast.LENGTH_LONG).show(); } } else{ // progressDialog.dismiss(); // Toast.makeText(CNM_MapsActivity.this, "Error Please Try Again", Toast.LENGTH_SHORT).show(); Snackbar.make(mn,"Error Please Try Again",Snackbar.LENGTH_SHORT).show(); // onResetMap(); } ,它的速度快19倍以上。通过减少总和为平方数的检查次数并加快检查速度来提高速度。我还移动了平方数检查以减少例程调用自身的次数。

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

n = 15

答案 3 :(得分:0)

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

并且当您使用(p%1 == 0)时,另一个总是True

并删除重复项,请更正您的代码,然后您可以轻松地将列表变成这样的集合:

NoDuplicatedList = set(t)

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

您仍然可能会失去列表的顺序。