Python中列表的高级(可能)选择规则

时间:2016-04-19 04:23:23

标签: python loops

给出一个列表

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”和“b”之间。

现在,从list_中的第一个元素开始(总是“a”):

  1. l_a获取元素,直到您点击“b”(在这种情况下:[v1, V2])。表单“v1+v2”作为字典的键(相应的值在下面的步骤2中)。这是我们目前的关键。
  2. 从l_b获取元素直到你点击“a”(在这种情况下只是[w1,w2,w3])。将“w1 + w2 + w3”存储为当前密钥下的值。
  3. 重复
  4. 当然,我尝试过很多循环内容,但它很快就难以预订,让我觉得有一种比嵌套循环更好的方法。

    问题: 所以,简单地说,我该如何以有效的方式做到这一点?

    谢谢

3 个答案:

答案 0 :(得分:3)

也许这会给你一些想法。

你真正想要做的是将重复的项目组合在一起(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]

答案 1 :(得分:0)

另一种类似的方法:

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!='']

这将为您提供连续ab的数量。然后,您可以使用它来汇总并创建密钥。注意:使用np.cumsum(zip(n_a ,n_b))应该为您提供相关的指数来汇总。

答案 2 :(得分:0)

这是一个相当简单的解决方案:

# 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]}