Python 如何在列表中执行多个操作
如何让它在(0,50)之间选择5个随机数,然后在(0,12)之间选择2个随机数?不要重复使用名称Python 如何在列表中执行多个操作,python,list,operation,Python,List,Operation,如何让它在(0,50)之间选择5个随机数,然后在(0,12)之间选择2个随机数?不要重复使用名称列表。一种方法是循环遍历边界的一个iterable,并将其发送到randint L = [random.randint(0,50) for i in range(5) random.randint(0,12) for i in range(2)] 您还可以使用itertools.chain和itertools.repeat来避免构建边界列表 from random import randint l
列表。一种方法是循环遍历边界的一个iterable,并将其发送到randint
L = [random.randint(0,50) for i in range(5) random.randint(0,12) for i in range(2)]
您还可以使用itertools.chain
和itertools.repeat
来避免构建边界列表
from random import randint
lst = [randint(*bounds) for bounds in [(0, 50)]*5 + [(0, 12)]*2]
您可以根据i
的值将第二个参数更改为randint()
:
lst = [randint(*bounds) for bounds in chain(repeat((0, 50), 5), repeat((0, 12), 2))]
可能性是无穷的。Lambdas,randint(0,上限)
,randint(*args)
,这是一个函数,它的结果会根据调用频率的不同而变化,等等。但我不认为这些函数实际上更可读或更容易理解
对于本例,仅使用7个值,我将连接两个列表:
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]
因为它更干净,可读性更强。创建包含两个列表理解结果的第三个列表的性能成本很小,在这里可以忽略不计。类似于这样的东西,连接两个列表:
[randint(0, 50) for _ in range(5)] + [randint(0, 12) for _ in range(2)]
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)
如果您乐于使用第三方库,您可以通过NumPy:
from random import randint
my_list = [randint(0,50) for i in range(5)] + [randint(0,12) for i in range(2)]
这种方法的好处,即内存预分配,将在较大的阵列中体现出来
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.])
lst=[random.randint(0,50),如果i<5,则为random.randint(0,12),表示范围(7)内的i]
打印(lst)#[7,10,40,4,38,1,5]
您可以使用列表理解和内置功能来完成此操作,一些怪物如:
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]
也许,如果您想使用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循环,一种幼稚的方法。它将是高效、简单和可读的。除了展示之外,我认为上述方法在生产代码中没有任何优势。这里有另一个变体,可以避免在每次迭代中进行if
测试。它还使用randrange
,这比randint
的效率略高
>>> from itertools import chain, repeat, starmap
>>> list(starmap(random.randint, chain(repeat((0,50),5), repeat((0,12),2))))
[16, 47, 40, 21, 15, 12, 4]
典型输出
from random import randrange
lst = [randrange(hi) for num, hi in ((5, 51), (2, 13)) for _ in range(num)]
print(lst)
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)
这相当于
[10, 31, 46, 25, 23, 6, 5]
外部循环选择num
、子列表中的项目数和该子列表的hi
随机范围的大小;内部循环在所需范围内生成所需数量的随机数
FWIW,这里有一些代码比较已经提交的各种算法。它还验证了当给定相同的随机种子时,它们产生相同的结果。我的简单验证代码使用了eval
,所以它只能测试表达式,不能测试语句,所以它不能测试jpp或Abhishek的代码;此外,jpp的Numpy代码给出了不同的结果,因为它使用了不同的种子算法。请参阅timeit
文档,了解timeit
的功能以及如何解释结果
lst = []
for num, hi in ((5, 51), (2, 13)):
for _ in range(num):
lst.append(randrange(hi))
正如您所看到的,jpp的Numpy代码是最快的。我预计,如果我们生成更长的数字列表,速度差异将更加明显
这些计时是在一台古老的32位单核2GHz机器上执行的,该机器在Debian派生发行版上运行Python 3.6.0。YMMV
以下是在相同范围内生成50+20=70个值的列表(或数组)的计时
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]
你想要的产量是多少?不要给你的列表命名list
list理解只适用于构建列表的循环。如果您可以在常规的for
循环中使用列表。附加(…)
部分来表达您的需求,那么您可能也可以将其作为列表理解。它在这里只是命名列表,而不是在我的实际代码中。我想要的结果是一个由7个随机数组成的列表,其中5个从(0,50)范围内选取,2个从(0,12)范围内选取。您可能对我添加到答案中的timeit
结果感兴趣。完美的人,谢谢!我一定是在沮丧中错过了!美好的我想我唯一不喜欢列表理解的地方就是可读性。@artomason:那取决于你是如何使用它们的。在这里,表达式很容易太难看。对于7个值,比较计时几乎没有意义。从性能的角度来看这确实是一个过早的优化。
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]
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]