Python 有效配对列表的随机元素
我有一个Python 有效配对列表的随机元素,python,list,performance,Python,List,Performance,我有一个n元素列表,上面写着:foo=['a','b','c','d','e'] 我想随机配对此列表中的元素以接收,例如: bar=['a','c'],['b','e']]如果列表的长度不是偶数,最后一个元素将被丢弃 现在,我有一个蛮力函数: def rnd_对(foo): 而len(foo)>1: pair_idxs=np.sort(np.random.choice(range(len(foo)),2,replace=False)) el_pair=[foo.pop(pair_idxs[0])
n
元素列表,上面写着:foo=['a','b','c','d','e']
我想随机配对此列表中的元素以接收,例如:
bar=['a','c'],['b','e']]
如果列表的长度不是偶数,最后一个元素将被丢弃
现在,我有一个蛮力函数:
def rnd_对(foo):
而len(foo)>1:
pair_idxs=np.sort(np.random.choice(range(len(foo)),2,replace=False))
el_pair=[foo.pop(pair_idxs[0]),foo.pop(pair_idxs[1]-1)]
el_对。追加(el_对)
这不是很有效。另外,我不喜欢在适当的地方更改列表。有没有更有效的方法?提前谢谢。我想说这是最具python风格的处理方式:
foo = ['a', 'b', 'c', 'd', 'e', 'f']
random.shuffle(foo)
length = len(foo)//2
result = list(zip(foo[:length], foo[length:]))
Zip将在多个列表的同一索引处组合元素,并在一个列表的元素用完时停止。因此,您将对列表进行洗牌,取列表的上半部分和下半部分,然后按元素组合它们,直到较短的一部分用完元素
编辑:你说你对不同处理方式的表现感兴趣。我在这里为每个独特的答案制作了一个函数,并对它们计时:
def a(foo):
random.shuffle(foo)
length = len(foo)//2
return list(zip(foo[:length], foo[length:]))
def b(foo):
random.shuffle(foo)
return [[foo[i], foo[i+1]] for i in range(0, len(foo)-(len(foo)%2), 2)]
def c(foo):
np.random.shuffle(foo)
return foo[:len(foo)-(len(foo)%2)].reshape(2,-1)
def d(foo):
result = []
for i in range(1, len(foo), 2):
result.append([foo[i-1], foo[i]])
return result
def e(foo):
el_pairs = []
while len(foo) > 1:
pair_idxs = np.sort(np.random.choice(range(len(foo)), 2, replace=False))
el_pair = [foo.pop(pair_idxs[0]), foo.pop(pair_idxs[1] - 1)]
el_pairs.append(el_pair)
return el_pairs
def f(foo):
random.shuffle(foo)
length = len(foo)//2
return zip(foo[:length], foo[length:])
Zip无列表:
%timeit f(foo)
3.96 µs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
邮编:
列表理解:
%timeit b(foo)
4.38 µs ± 22.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
For循环:
%timeit d(foo)
812 ns ± 5.68 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
原件:
%timeit e(foo)
154 ns ± 1.11 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
给出的numpy答案对我来说不是现成的。试试这个:
>>> import random
>>> foo = ['a', 'b', 'c', 'd', 'e']
>>> random.shuffle(foo)
>>> bar = list(zip(foo[::2], foo[1::2]))
>>> bar
[('e', 'd'), ('c', 'a')]
from random import shuffle
foo = ['a', 'b', 'c', 'd', 'e']
shuffle(foo)
result = []
for i in range(1, len(foo), 2):
result.append([foo[i-1], foo[i]])
print(result)
我对表演部分更感兴趣。我将编辑标题。谢谢你展示另一个问题。别忘了,如果你觉得所有答案都有用的话,你可以在这里向上投票:)@oezguensidont获得向上投票吗?关于性能方面,这不是重复的。我也在测试答案的速度,可以确认。感谢您为长度为1e4的序列所做的努力,与d相比,使用numpy运行速度快了10倍
from random import shuffle
foo = ['a', 'b', 'c', 'd', 'e']
shuffle(foo)
result = []
for i in range(1, len(foo), 2):
result.append([foo[i-1], foo[i]])
print(result)
import random
import string
def random_pairs(x):
random.shuffle(x)
return zip(*(2 * [iter(x)]))
# Shuffling in place.
array = list(string.lowercase) # a-z
print list(random_pairs(array))
# Not Shuffling in place.
array = list(string.uppercase) # A-Z
pairs = random_pairs(range(len(array)))
print map(lambda pair: map (lambda i: array[i], pair), pairs)