我有以下问题。它从我得到的列表开始。比方说,我得到了列表: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 三等级。这是我得到的第二等级和三等级的不同字符串的数量。
我认为这是一个棘手的问题,但我猜有些命令我不知道可以提供帮助。希望你能给我一些提示:)
答案 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")