L = [random.randint(0,50) for i in range(5) random.randint(0,12) for i in range(2)]
如何获取(0,50)之间的5个随机数,然后选择(0,12)之间的2个随机数?
答案 0 :(得分:8)
您可以根据randint()
的值将第二个参数更改为i
:
[randint(0, 50 if i < 5 else 12) for i in range(7)]
50 if i < 5 else 12
表达式将更改最后两次迭代传递给random.randint()
的内容。
您可以在其中输入更多的变化形式。列表推导是一堆循环和if
过滤器,它们重复执行前面的表达式。根据表达式中的迭代值,有很多方法可以将变元变种到函数调用中。
例如,您可以将这些参数记录在functools.partial()
objects中:
from functools import partial
from random import randint
rint50 = partial(randint, 0, 50)
rint12 = partial(randint, 0, 12)
[rint() for rint in [rint50] * 5 + [rint12] * 2]
可能性是无限的。 Lambdas,randint(0, upperbound)
,randint(*args)
这个函数会根据调用的频率等不同而改变结果。但是,我不认为其中任何一个实际上更具可读性或可理解性。
在这种情况下,只有7个值,我将两个列表连接起来:
[randint(0, 50) for _ in range(5)] + [randint(0, 12) for _ in range(2)]
因为它更干净,更易读。在此处创建包含两个列表理解结果的第三个列表的性能开销很小,可以忽略不计。
答案 1 :(得分:4)
可能是这样,将2个列表串联在一起:
from random import randint
my_list = [randint(0,50) for i in range(5)] + [randint(0,12) for i in range(2)]
答案 2 :(得分:3)
请勿重复使用名称list
。一种方法是遍历边界的迭代,并将其发送到randint
from random import randint
lst = [randint(*bounds) for bounds in [(0, 50)]*5 + [(0, 12)]*2]
您还可以使用itertools.chain
和itertools.repeat
来避免建立边界列表
lst = [randint(*bounds) for bounds in chain(repeat((0, 50), 5), repeat((0, 12), 2))]
答案 3 :(得分:1)
import random
l = [random.randint(0,50) for i in range(5)]
l.extend([random.randint(0,12) for i in range(2)])
print(l)
答案 4 :(得分:1)
这是另一个避免每次迭代都进行if
测试的变体。它还使用randrange
,效率比randint
略高。
from random import randrange
lst = [randrange(hi) for num, hi in ((5, 51), (2, 13)) for _ in range(num)]
print(lst)
典型输出
[10, 31, 46, 25, 23, 6, 5]
这等效于
lst = []
for num, hi in ((5, 51), (2, 13)):
for _ in range(num):
lst.append(randrange(hi))
外部循环选择num
,子列表中的项数和hi
子列表的随机范围的大小;内部循环会在所需范围内生成所需数量的随机数。
FWIW,这是一些timeit
代码,用于比较已提交的各种算法。它还验证了在给定相同的随机种子时它们是否产生相同的结果。我的简单验证代码使用eval
,因此它只能测试表达式,而不能测试语句,因此不能测试jpp或Abhishek的代码。此外,由于jpp的Numpy代码使用了不同的播种算法,因此无论如何都会给出不同的结果。有关timeit
的功能以及如何解释结果的信息,请参见timeit
文档。
from timeit import Timer
import random
from random import randint, randrange, seed
from itertools import chain, repeat, starmap
from functools import partial
import numpy as np
imports = 'random, randint, randrange, seed, chain, repeat, starmap, partial, np'
commands = (
('Martijn', '', '[randint(0, 50 if i < 5 else 12) for i in range(7)]'),
('Martijn_partial',
'rint50 = partial(randint, 0, 50); rint12 = partial(randint, 0, 12)',
'[rint() for rint in [rint50] * 5 + [rint12] * 2]'
),
('Patrick', '', '[randint(*bounds) for bounds in [(0, 50)]*5 + [(0, 12)]*2]'),
('Patrick_chain', '',
'[randint(*bounds) for bounds in chain(repeat((0, 50), 5), repeat((0, 12), 2))]'
),
('Ralf', '', '[randint(0,50) for i in range(5)] + [randint(0,12) for i in range(2)]'),
('Abhishek', '', 'l = [random.randint(0,50) for i in range(5)];'
'l.extend([random.randint(0,12) for i in range(2)])'
),
('PM 2Ring', '', '[randrange(hi) for num, hi in ((5, 51), (2, 13)) for _ in range(num)]'),
('jpp', '', 'A = np.zeros(7); '
'A[:5] = np.random.randint(0, 20, 5); A[5:] = np.random.randint(0, 12, 2)'
),
('Tanmay jain', '',
'[random.randint(0,50) if i < 5 else random.randint(0,12) for i in range(7)]'
),
('juanpa', '', '[random.randint(a,b) for args in (((0,50) for _ in range(5)),'
'((0, 12) for _ in range(2))) for a, b in args]'
),
('juanpa_starmap', '', 'list(starmap(random.randint,'
'chain(repeat((0,50),5), repeat((0,12),2))))'
),
)
def verify():
for name, setup, cmd in commands:
if name in ('jpp', 'Abhishek'):
continue
seed(17)
if setup:
exec(setup)
print('{:16}: {}'.format(name, eval(cmd)))
print()
def time_test(loops):
timings = []
print('loops =', loops)
for name, setup, cmd in commands:
setup = 'from __main__ import ' + imports + ';' + setup
t = Timer(cmd, setup=setup)
result = sorted(t.repeat(3, loops))
timings.append((result, name))
timings.sort()
for result, name in timings:
print('{:16} : {}'.format(name, result))
verify()
time_test(5000)
典型输出
Martijn : [33, 26, 19, 23, 18, 2, 12]
Martijn_partial : [33, 26, 19, 23, 18, 2, 12]
Patrick : [33, 26, 19, 23, 18, 2, 12]
Patrick_chain : [33, 26, 19, 23, 18, 2, 12]
Ralf : [33, 26, 19, 23, 18, 2, 12]
PM 2Ring : [33, 26, 19, 23, 18, 2, 12]
Tanmay jain : [33, 26, 19, 23, 18, 2, 12]
juanpa : [33, 26, 19, 23, 18, 2, 12]
juanpa_starmap : [33, 26, 19, 23, 18, 2, 12]
loops = 5000
jpp : [0.23938178099342622, 0.24184146700281417, 0.3152835669970955]
PM 2Ring : [0.26918871099769603, 0.27244400099880295, 0.2916741489971173]
Patrick : [0.34155847399961203, 0.34415175200410886, 0.3531294650019845]
juanpa_starmap : [0.3417540490045212, 0.34329504700144753, 0.3438059809996048]
Martijn : [0.3509639670010074, 0.362117896998825, 0.547288200003095]
Martijn_partial : [0.3511254819968599, 0.35262946599686984, 0.39430355399963446]
Patrick_chain : [0.3541102219969616, 0.3545923809942906, 0.3555165420038975]
Tanmay jain : [0.3558294050017139, 0.5510739650053438, 0.7693202439986635]
Ralf : [0.3678122450000956, 0.44522786799643654, 0.44827762299973983]
juanpa : [0.4089203829935286, 0.41227930299646687, 0.42410747800022364]
Abhishek : [0.4811078249986167, 0.4942625819967361, 0.6255962599971099]
如您所见,jpp的Numpy代码是最快的。我希望如果我们生成更长的数字列表,速度差异会更加明显。
这些计时是在古老的32位单核2GHz机器上执行的,该机器在Debian衍生发行版上运行Python 3.6.0。 YMMV。
以下是在相同范围内生成50 + 20 = 70个值的列表(或数组)的时间。
loops = 500
jpp : [0.025625186994147953, 0.025764200996491127, 0.03122780400008196]
PM 2Ring : [0.21989007600495825, 0.2200367909972556, 0.22065802400175016]
juanpa_starmap : [0.3094131350007956, 0.3110805670003174, 0.31563361900043674]
Patrick_chain : [0.3122365829985938, 0.31262181099737063, 0.3137894630053779]
Patrick : [0.3130071220002719, 0.31769691400404554, 0.3179219129960984]
Ralf : [0.31566168300196296, 0.3157304769993061, 0.3234770689959987]
Martijn : [0.3193310350034153, 0.3275600470005884, 0.35491854500287445]
Martijn_partial : [0.321399387998099, 0.3226969290044508, 0.32442738999816356]
Abhishek : [0.32655813400197076, 0.3363869300010265, 0.3657162370000151]
Tanmay jain : [0.32833286200184375, 0.33107244400162017, 0.39565577400207985]
juanpa : [0.35968791200139094, 0.3754627199959941, 0.3933205349967466]
答案 5 :(得分:0)
如果您很高兴使用第三方库,则可以通过NumPy:
import numpy as np
np.random.seed(0) # for consistency / testing
A = np.zeros(7)
A[:5] = np.random.randint(0, 20, 5)
A[5:] = np.random.randint(0, 12, 2)
array([ 12., 15., 0., 3., 3., 7., 9.])
这种方法的好处是,内存预分配在较大的数组中显而易见。
答案 6 :(得分:0)
since you want to pick 5 random values from 0 - 50( exclusive)
i = 0...4
and then you want to pick 2 random values from 0 - 12( exclusive)
i = 5 6
lst = [random.randint(0,50) if i < 5 else random.randint(0,12) for i in range(7)]
print(lst) # [7, 10, 40, 4, 38, 1, 5]
答案 7 :(得分:0)
您可以使用列表理解并且仅使用内置功能,有些怪异,例如:
index.html
也许,如果您想使用itertools,可以执行以下操作:
>>> result = [
... random.randint(a,b)
... for args in (((0,50) for _ in range(5)), ((0, 12) for _ in range(2)))
... for a, b in args
... ]
>>> result
[33, 38, 19, 9, 47, 0, 8]
这两种方法都很难阅读和简单。相反,我个人会使用两个for循环,即朴素的方法。这将是高效,简单和可读的。除了showboating,我认为在生产代码中上述方法没有任何优势。