重新排序列表以符合条件

时间:2019-11-08 20:20:47

标签: python list sorting optimization permutation

对于一所大学的某门课程,要求学生每周上课主题演讲。学生每周随机出现。

函数presOrder应该接收两个参数,(1)一个正整数n,表示演示的周数,(2)名称列表,该名称列表仅对于第一次演示。该函数返回一周的展示顺序的列表清单。每个列表以完全随机的顺序包含给定名称,以确保名称的顺序与前一周的顺序不同,并且每个名称的位置均与前一周的顺序不同。顺序不同意味着上周之前和之后的名称在下周应该不同。

import random
import itertools

def notRandom(lst, plst, no):
    result = True
    for i in range(no-1):
        result = result and (lst[i] == plst[i+1])
    result = result and (lst[no-1] == plst[0])
    if result:
        return True
    result = True
    for i in range(1,no):
        result = result and (lst[i] == plst[i-1])
    result = result and (lst[0] == plst[no-1])
    if result:
        return True
    return False


# My attempt
def presOrder(n, namelst):
    permutation = itertools.permutations(namelst)
    rand = [] + [namelst]
    prev = namelst
    for lst in permutation:
        if not(notRandom(lst, prev, len(namelst))) and len(rand) < n:
            rndom = True
            for i in range(len(namelst)):
                if not(lst[i] == prev[i]):
                    rndom = rndom and True
                else:
                    rndom = rndom and False
            if rndom:
                rand += [lst]
                prev = lst[:]
        else:
            continue
    return rand


names = ['Abi Jones', 'Bob King', 'Carl Llewellyn', 'Danielle McIntosh', 'Earl Newell', 'Frank Olephante', 'George Brown', 'Harry Zephers']

#example
>>> print(presOrder(5, names))
>>> [['Abi Jones', 'Bob King', 'Carl Llewellyn', 'Danielle McIntosh', 'Earl Newell', 'Frank Olephante', 'George Brown', 'Harry Zephers'], ('Bob King', 'Abi Jones', 'Danielle McIntosh', 'Carl Llewellyn', 'Frank Olephante', 'Earl Newell', 'Harry Zephers', 'George Brown'), ('Carl Llewellyn', 'Bob King', 'Abi Jones', 'Danielle McIntosh', 'Earl Newell', 'Frank Olephante', 'George Brown', 'Harry Zephers'), ('Danielle McIntosh', 'Abi Jones', 'Bob King', 'Carl Llewellyn', 'Frank Olephante', 'Earl Newell', 'Harry Zephers', 'George Brown'), ('Earl Newell', 'Bob King', 'Abi Jones', 'Danielle McIntosh', 'Carl Llewellyn', 'Frank Olephante', 'George Brown', 'Harry Zephers')]

该代码似乎可以(某种程度上)正常工作,但我需要对其进行更多测试。同时,如何优化presOrder的代码?

1 个答案:

答案 0 :(得分:0)

我的方法是这样的:

Array.from(buttons).forEach(
    button => button.addEventListener("click", openMenuItemAll)
);

想法是首先创建名称列表的(随机重新排序(随机))版本。
然后添加下一个经过改组的版本-但要反复进行改组,直到满足您的两个要求。
直到列表的长度== n。

这两个要求在public static List<String> getChromeDownloadFiles(WebDriver driver) { // Get the current windows String handle = driver.getWindowHandle(); ArrayList<String> otabs = new ArrayList<String> (driver.getWindowHandles()); int sz = otabs.size(); // Open a new TAB ((JavascriptExecutor) driver).executeScript("window.open();"); ArrayList<String> ltabs = new ArrayList<String> (driver.getWindowHandles()); driver.switchTo().window(ltabs.get(sz)); driver.get("chrome://downloads/"); List<String> res = new ArrayList<>(); try { Thread.sleep(20000); } catch (InterruptedException e1) { } try { // This uses #shadow-root elements which are a bit tricky and need to be found and expanded WebElement root1 = driver.findElement(By.tagName("downloads-manager")); WebElement shadowRoot1 = expandRootElement(driver, root1); WebElement ironList = shadowRoot1.findElement(By.tagName("iron-list")); Thread.sleep(10000); List<WebElement> fileElements = ironList.findElements(By.tagName("downloads-item")); for (WebElement e : fileElements) { WebElement sh = expandRootElement(driver, e); List<WebElement> divs = sh.findElements(By.tagName("div")); WebElement div = null; for (WebElement d : divs) { if (d.getAttribute("id").contentEquals("content")) { div = d; break; } } WebElement imgEle = div.findElement(By.xpath(".//img[@class='icon']")); String src = imgEle.getAttribute("src"); String pt1 = src.replaceAll("chrome.*path=", ""); String[] split = pt1.split("&"); String ptraw = split[0]; // the uri is encoded so it must be decoded. Unfortunately, decoding does not // replace "+" with " " URI uri = new URI(ptraw); String p = uri.getPath(); p = p.replace("+", " "); res.add(p); } } catch (Exception ex) { System.out.println(ex.getMessage()); } // Go to the previous driver.close(); driver.switchTo().window(handle); return res; } 函数中实现。
我认为关于职位的第一个是自我解释。
第二个检查是否最后一行的任何邻居在最后一行中也作为邻居出现。
为此,有一个帮助程序功能可创建邻居对的列表。

请注意,邻居定义中的import random def test_positions(L1, L2): return any(a==b for a, b in zip(L1, L2)) def neighbours(L): return [set([a, b]) for a, b in zip(L[:-1], L[1:])] def test_neighbours(L1, L2): return any(nb in neighbours(L2) for nb in neighbours(L1)) def pres_order(n, L): result = [names[:]] # random.shuffle(result[0]) # only needed for reording first row for i in range(1, n): result.append(names[:]) random.shuffle(result[-1]) while test_positions(result[-1], result[-2]) or test_neighbours(result[-1], result[-2]): random.shuffle(result[-1]) return result 函数将防止相邻行中的邻居名称对与其顺序无关。如果您只想阻止一对的精确复制(例如,应允许test_... set之后但不允许[...'E', 'G',... ]之后),则可以简单地将set函数保留下来。


示例:

[...'G', 'E',... ]

编辑: 我只是意识到第一行应该是未更改的原始列表。因此,我评论了第一次洗牌;因此您可以根据需要轻松地将其取回。