列表的特殊顺序

时间:2016-09-22 20:56:34

标签: python list

我有以下问题。它从我得到的列表开始。比方说,我得到了列表:A=['1-00', '10--'](列表可以更长甚至更短,例如B=['01-1', '1-00', '0-01'])。它还可以有超过四个或更少的条目。现在我首先要排序等级。排名定义为您看到的位数。

在A中,我有一个等级为2 '10--'的字符串和等级为3 '1-00'的字符串。 (在B中我有三个等级三)现在我需要得到四个二进制数字的数字,我得到的所有最低排名字符串首先。

这里我只有一个等级两个字符串'10--'我可以产生:'1000', '1001', '1010', '1011'。所以我得到第二等级的 4 二进制数。使用'1-00',我得到'1100''1000'。但我已经获得了排名第二的第二个字符串。所以我应该得到的数字是 5 三等级。这是我得到的第二等级和三等级的不同字符串的数量。

我认为这是一个棘手的问题,但我猜有些命令我不知道可以提供帮助。希望你能给我一些提示:)

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你想首先按固定数字(“rank”)的数量排序,然后计算每个等级或低于等级的唯一可能比特串的总数。因此,对于A,您希望它排序为['10--', '1-00'](将排名降至第一位),并且您希望获得所有排名2和更低排列模式的唯一模式数量(在这种情况下) ,只有一个),然后是所有等级3和更低的模式(再次,在这种情况下,只有一个),等等。

如果理解正确,第一步是排序:

A.sort(key=lambda x: x.count('0') + x.count('1'))
# Or if all patterns are of length 4, the slightly simpler:
A.sort(key=lambda x: 4 - x.count('-'))

之后,您使用itertools.groupby按排名处理,使用itertools.product生成唯一输出并将其存储在set中,以便删除重复项:

from __future__ import print_function  # For consistent print on Py2/Py3
from future_builtins import map  # Only on Py2, to get Py3 generator based map

from itertools import groupby, product

uniquebits = set()
for rank, pats in groupby(A, key=lambda x: x.count('0') + x.count('1')):
    for pat in pats:
        # product can be abused to sub 0, then 1 for each wildcarded space
        patpieces = [let if let != '-' else '01' for let in pat]
        # Generate all patterns (using ''.join reduces storage by converting
        # tuples back to str) updating the set to get unique values seen so far
        uniquebits.update(map(''.join, product(*patpieces)))
    print("For rank", rank, "and below,", len(uniquebits), "unique bit strings")

您的A将输出哪个:

For rank 2 and below, 4 unique bit strings
For rank 3 and below, 5 unique bit strings

如果你想避免间隙,并将所有等级的输出输出到模式的最大长度,它会稍微复杂一些(因为groupby只有当至少有一个带有“key”的输入时才产生组,在这种情况下,给定等级的至少一个输入):

lastrank = None  # Change to 1 or 2 to force ranks prior to lowest rank to output
for rank, pats in groupby(A, key=lambda x: x.count('0') + x.count('1')):
    if lastrank is not None and lastrank + 1 != rank:
        for fillrank in range(lastrank + 1, rank):
            print("For rank", fillrank, "and below,", len(uniquebits), "unique bit strings")
    lastrank = rank

    for pat in pats:
        # product can be abused to sub 0, then 1 for each wildcarded space
        patpieces = [let if let != '-' else '01' for let in pat]
        # Generate all patterns (using ''.join reduces storage by converting
        # tuples back to str) updating the set to get unique values seen so far
        uniquebits.update(map(''.join, product(*patpieces)))
    print("For rank", rank, "and below,", len(uniquebits), "unique bit strings")

# Or len(max(A, key=len))+1 if uneven lengths
for rank in range(lastrank + 1, len(A[0]) + 1):
    print("For rank", rank, "and below,", len(uniquebits), "unique bit strings")