循环遍历列表吗?

时间:2019-05-24 05:41:51

标签: python python-2.7

我一直试图通过这种方式来思考,但是还无法获得一个干净的解决方案。 所以,我有一个列表列表,如..

data = [ 
 [1,2,3],
 ['a','b'],
 ['fush', 'bush', 'mish', 'bish']
]

我想从中取样“ k”值。 例如,如果k = 2,则它可以返回类似[2, 'b']的内容(并将其从考虑范围中删除)。

如果k = 4,则它应返回类似[3, 'a','bush', 1]的内容。

8 个答案:

答案 0 :(得分:2)

怎么样?

import random

from itertools import chain, zip_longest

def special_sample(data, n):
    length = len(data)
    n_elements, excess = divmod(n, length)
    samples = (random.sample(sub, n_elements + 1) 
               if index < excess 
               else random.sample(sub, n_elements)
               for index, sub in enumerate(data))
    return [element for element in chain.from_iterable(zip_longest(*samples)) if element is not None]

special_sample(data, 4)

输出:

[3, 'a', 'bush', 1]

答案 1 :(得分:1)

您可以先使用random.shuffle来随机整理data中的每个子列表,压缩并链接子列表,然后使用itertools.islice来获取前k个项目:

import random
from itertools import islice, chain
k = 4
for l in data:
    random.shuffle(l)
print(list(islice(chain.from_iterable(zip(*data)), k)))

示例输出:

[1, 'a', 'mish', 3]

答案 2 :(得分:1)

您可以尝试一下 注意:我假设您想每次删除列表的第一个元素,可以用随机索引替换它

data = [
 [1,2,3],
 ['a','b'],
 ['fush', 'bush', 'mish', 'bish']
]

def sampleList(k, data):
  sampledList = []
  dl = len(data)
  for idx in range(0,k):
    # assuming here that we sample the first element of list always
    d = data[idx % dl] # wrap around the index
    sampledList.append(d[0]) # Add sampled value to return list
    del d[0] # Delete sampled value from original list

  return sampledList

print sampleList(2, data)
print data

print sampleList(4, data)
print data

此输出为

[1, 'a']
[[2, 3], ['b'], ['fush', 'bush', 'mish', 'bish']]
[2, 'b', 'fush', 3]
[[], [], ['bush', 'mish', 'bish']]

希望这会有所帮助。

答案 3 :(得分:0)

您也可以这样做:

import random

def fun(data, k):
  output = []
  for i in range(k):
      if i > len(data):
        # if i is greater than len of data then reset i
        i = i % len(data)  

      # select a random element from sublist and remove it.
      x = random.choice(data[i])
      output.append(x)
      data[i].remove(x)
  return output

print(fun(data, 3))

输出:

[3, 'b', 'bish']

# data
# [[1, 2], ['a'], ['fush', 'bush', 'mish']]

答案 4 :(得分:0)

再次采用另一种方法。首先,您必须一次flatten your list of lists一次,即

flat_data = [item for sublist in data for item in sublist]

,然后填写另一个列表,直到完成基于k的采样为止。

import random as rd
k      = 4
sample = []

while len(sample) < k:
    if rd.random() > .5:
        rd.shuffle(flat_data) # costly
        sample.append(
            flat_data.pop(0)
        )
# where sample now is, say, ['b', 'bish', 2, 'a']

答案 5 :(得分:0)

如果您使生成器生成随机播放,请吐出随机值,然后再次随机播放,您可以循环遍历这些生成器,以永远以正确的顺序吐出值。每次用完都会重新洗牌:

从itertools导入周期开始,链式

def randGen(l):
    while True:
        r = random.sample(l, k=len(l))
        yield from r

data = [ [1,2,3],['a','b'],['fush', 'bush', 'mish', 'bish']]

gs = map(next, cycle(randGen(l) for l in data)) # setup a generator on the cycle 

for i in range(30):
    print(next(gs), end = ",")

结果

1,b,bush,3,a,bish,2,b,mish,3,a,fush,1,a,fush,2,b,bish,1,a,mish,3,b,bush,2,a,bish,1,b,mish ...

如果您只想要列表中的某个数字,islice()使其非常方便:

list(islice(gs, 9))

# [2, 'a', 'mish', 1, 'b', 'bish', 3, 'b', 'fush']

答案 6 :(得分:0)

好吧,这个答案可能太晚了,可能效率不高,但是我还是决定试一试:

import random
data = [
 [1, 2, 3],
 ['a', 'b'],
 ['fush', 'bush', 'mish', 'bish']
]
k = 5
sample_list = []


def filter_chosen_element(sample_list1, data1):
    for i in range(len(data1)):
        for j in range(len(sample_list1)):
            if sample_list1[j] in data1[i]:
                data1[i].remove(sample_list1[j])


if k <= len(data):
    for i in range(k):
        sample_list.append(random.choice(data[i]))
        filter_chosen_element(sample_list, data)
else:
    for i in range(k):
        sample_list.append(random.choice(data[i % 3]))
        filter_chosen_element(sample_list, data)

print(sample_list)
print(data)

答案 7 :(得分:0)

您可以使用列表的索引创建排列,创建一个矩阵,其列为这些索引,然后将矩阵展平,从而按使用顺序为您提供数组的索引。

由于某些列表比其他列表长,因此请根据最短的列表限制索引的长度。

def sample_from_matrix(data, k):
    min_size = min([len(i) for i in data])
    indexes = np.column_stack ( [ np.random.permutation(min_size) for i in data ] )
    indexes = indexes.flatten()
    return [ data[i % len(data)][indexes[i]] for i in range(min(k, len(indexes))) ]