给定的是一个列表
list_ = [a,a,b,b,b,a,b,a,b,b,...,b]
和另外两个列表
l_a = [v1,v2,...,vN]
l_B = [w1,w2,...,wN].
list_的第一个元素总是"a
"。其余元素可以以任何随机的方式在"a
"one_answers"b
"之间混合。
现在,从列表中的第一个元素开始_(它总是"a"):
- 从
l_a
中获取元素,直到达到"b
"(在本例中:[v1,v2])。将"v1+v2
"形成为字典的关键字(相应的值在步骤2中。以下)。这是我们目前的钥匙 - 从l_b中提取元素,直到达到"a"(在本例中仅为[w1,w2,w3])。将"
w1 + w2 + w3
"作为值存储在当前密钥下 - 重复
当然,我尝试过很多循环的东西,但很快就很难记账,这让我觉得有比嵌套循环更好的方法。
问题:那么,简单地说,我该如何以有效的方式做到这一点?
感谢
也许这会给你一些想法。
你真正想做的是将重复的项目分组在一起(itertools.groupby非常适合),然后从列表的开头删除这些项目(你也可以不使用列表,只保留当前位置的索引并进行切片)。
import itertools
import random
import collections
choices = ['a', 'b']
list_ = [random.choice(choices) for _ in range(30)]
l_a = collections.deque([random.randint(1, 100) for _ in range(list_.count('a'))])
l_b = collections.deque([random.randint(1, 100) for _ in range(list_.count('b'))])
# Everything above is to build up the sample data.
# You can wrap your existing l_a, l_B lists in a collections.deque
# make a dictionary that holds the two dequeues keyed by the character we find in list_
lists_by_char = {'a': l_a, 'b': l_b}
# print it out to make sure we aren't cheating
print(list_)
print(l_a)
print(l_b)
for k, g in itertools.groupby(list_):
# k will be the letter 'a' or 'b'
# g will be the items in a _grouper. We can call list on that to get the actual items. But what we care about is the length of that list.
items = [lists_by_char.get(k).popleft() for _ in range(len(list(g)))]
# The we call popleft on the deque matching our current character as many times as our list of characters is long.
print(k, items)
示例输出-每次运行时都会有所不同
['a', 'a', 'b', 'b', 'b', 'a', 'a', 'a', 'b', 'a', 'b', 'b', 'a', 'b', 'b', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'a', 'a']
deque([36, 61, 7, 17, 25, 76, 2, 72, 15, 33, 1, 53, 54, 49, 29, 68])
deque([55, 95, 97, 24, 72, 14, 54, 98, 91, 98, 57, 56, 40, 17])
a [36, 61]
b [55, 95, 97]
a [7, 17, 25]
b [24]
a [76]
b [72, 14]
a [2]
b [54, 98, 91]
a [72, 15, 33, 1, 53]
b [98, 57]
a [54, 49]
b [56, 40, 17]
a [29, 68]
另一种类似的方法:
list_ = "aabbbababbb"
n_a = [len(x) for x in list_.split('b') if x!='']
n_b = [len(x) for x in list_.split('a') if x!='']
这将为您提供连续a
和b
的编号。然后,您可以使用它来求和并创建密钥。注意:使用np.cumsum(zip(n_a ,n_b))
应该会给你相关的指数来求和。
这里有一个相当简单的解决方案:
# given
a = "A"
b = "B"
l = [a,a,b,b,b,a,b,a,b,b,b] # ['A', 'A', 'B', 'B', 'B', 'A', 'B', 'A', 'B', 'B', 'B']
l_a = range(0, 2*len(l), 2) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
l_b = range(1, 2*len(l)+1, 2) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
d = {}
making_l_a_key = True
making_l_b_val = False
key = ()
value = []
for index, item in enumerate(l):
if item == a and making_l_b_val:
making_l_a_key = True
making_l_b_val = False
d[tuple(key)] = value
key = ()
value = []
if item == b and making_l_a_key:
making_l_a_key = False
making_l_b_val = True
if item == a and making_l_a_key:
key += (l_a[index], )
if item == b and making_l_b_val:
value.append(l_b[index])
d[key] = value
print d
输出:
{(10,): [13], (0, 2): [5, 7, 9], (14,): [17, 19, 21]}