如何计算循环函数的第一次重复?
How to calculate first repetition of a looping function?
我是 Python 的新手,对以下作业有疑问。
import random
print(random.randint(1, 100))
如何计算重复的随机数(使用字典)?
输出应该是这样的:
>>> repeat (1, 100)
([random1, random2, random3, ...], number of loops until the first repetition is reached)
谢谢。
您可以只初始化一个集合,然后循环获取一个随机数并检查它是否已经在集合中,如果是则退出,否则将其添加到集合并继续。
不是使用字典,而是函数 repeat
:
import random
def repeat(a, b):
l = []
while True:
l.append(random.randint(a, b))
if len(set(l)) != len(l):
break
return l
print(repeat(1, 100))
输出:
[13, 76, 32, 41, 59, 34, 43, 91, 28, 17, 53, 20, 46, 67, 37, 88, 16, 6, 92, 34]
你可以保留一个列表,并在该列表中不断添加你的随机数,当你发现你的随机数已经在你的列表中时,你就打破循环注意这是一个 O(n) 解决方案正弦您需要在整个列表中找到该元素
import random
my_list = []
while True:
#Generate random number
i = random.randint(1, 100)
#If it is already in the list, break the loop
if i in my_list:
break
#Append random number to list
my_list.append(i)
print(my_list)
输出可能看起来像
[5, 58, 84, 53]
[5, 29, 64, 52, 69, 53, 72, 41, 58, 50, 4, 68, 67, 22, 90, 32, 45, 17, 47, 89, 55, 6, 7, 46, 37, 88]
[17, 65, 46, 84, 30, 100, 48, 31, 80, 97, 70, 86, 47, 81, 13, 85, 60, 63, 22, 68, 8, 36, 99]
.....
@6502 已经指出的 O(1) 建议是将随机数附加为字典的键,这样查找会更快 O(1)
import random
my_dict = {}
while True:
#Generate random number
i = random.randint(1, 100)
#If it is already in the keys of dict, break the loop
if i in my_dict:
break
#Append random number as key of dict with value 0
my_dict[i] = 0
print(list(my_dict.keys()))
我们实际上可以使用 timeit
模块来检查改进,尽管它并不明显,因为随机数大小只有 1-100
首先是列表方法
In [21]: import random
...:
...: def get_list():
...: my_list = []
...: while True:
...: #Generate random number
...: i = random.randint(1, 100)
...: #If it is already in the list, break the loop
...: if i in my_list:
...: break
...: #Append random number to list
...: my_list.append(i)
...: return my_list
...:
In [22]: %timeit get_list()
16.9 µs ± 720 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
然后是字典方法
In [27]:
In [27]: import random
...:
...: def get_list():
...: my_dict = {}
...: while True:
...: # Generate random number
...: i = random.randint(1, 100)
...: # If it is already in the keys of dict, break the loop
...: if i in my_dict:
...: break
...: # Append random number as key of dict with value 0
...: my_dict[i] = 0
In [29]: %timeit get_list()
16.1 µs ± 567 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但是如果我们使用 1-10000 的范围,差异是明显的
In [38]: import random
...:
...: def get_list(upper):
...:
...: my_list = []
...: while True:
...: # Generate random number
...: i = random.randint(1, upper)
...: # If it is already in the list, break the loop
...: if i in my_list:
...: break
...: # Append random number to list
...: my_list.append(i)
...:
In [39]: %timeit get_list(10000)
287 µs ± 5.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [40]: import random
...:
...: def get_list(upper):
...:
...: my_dict = {}
...:
...: while True:
...: # Generate random number
...: i = random.randint(1, upper)
...: # If it is already in the keys of dict, break the loop
...: if i in my_dict:
...: break
...: # Append random number as key of dict with value 0
...: my_dict[i] = 0
...:
In [41]: %timeit get_list(10000)
155 µs ± 2.48 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
您可以看到列表方法花费的时间几乎是字典方法的两倍!
如果不需要维护生成数字的顺序,可以使用字典来做到这一点。
import random
def repeat_generator(min, max):
random_dict = {}
while True:
random_number = random.randint(min, max)
if random_dict.get(random_number):
break
else:
random_dict[random_number] = 1
print(random_dict.keys())
试试下面的代码。这会将每个随机数添加到字典中,然后使用它来检查随机数是否已经存在。你可以使用其他数据结构做同样的事情,但是,因为你提到了字典,所以我在这里使用它。
import random
rand_dict = {}
i = 0
while True:
rand_num = random.randint(1,100)
if rand_num in rand_dict:
print("random number already in dict. rand_num = %s, Number of Loops = %s" %(rand_num, i))
break
else:
i += 1
rand_dict[rand_num] = 1
输出:
random number already in dict. rand_num = 90, Number of Loops = 11
set
比dict
更适合这里,因为你只是想记录重复,dict
中的值在这里没用,O(1)次检查重复set
:
import random
def repeat(a, b):
nums = set()
count = 0
while len(nums) == count:
nums.add(random.randint(a, b))
count += 1
return list(nums)
这是一个高级解决方案。
首先,创建一个随机数生成器:
>>> import random
>>> random.seed(100) # to make it repeatable
>>> it = iter(lambda: random.randint(1,100), -1)
这是函数的鲜为人知的形式 iter
:第一个参数是一个函数,在到达哨兵之前一直被调用。由于 randint
永远不会 return -1
,这是一个无限的随机数生成器:
>>> import itertools
>>> list(itertools.islice(it, 15))
[19, 59, 59, 99, 23, 91, 51, 94, 45, 56, 65, 15, 69, 16, 11]
>>> list(itertools.islice(it, 15))
[95, 59, 34, 7, 85, 83, 27, 43, 30, 40, 99, 27, 23, 19, 25]
您可以根据需要获得任意数量的随机数。 (函数 islice
采用迭代器的 "slice")。现在,我们在不知道数字的情况下取数字:
>>> seen = set()
>>> list(itertools.takewhile(lambda x: x not in seen and not seen.add(x), it))
[45, 48, 81, 53, 27, 52, 60, 72, 36, 49, 21, 84, 82, 16, 24, 1, 78, 51, 19, 100, 73]
注意副作用:我们创建一个空集 s
来存储看到的数字,并且对于每个 x
,我们测试 x
是否在 seen
中(我们之前看到x
)然后将x
添加到seen
。诀窍是 seen.add(x)
总是 return None
,因此 not seen.add(x)
总是 True
和 b and not seen.add(x) == b and True == b
.
检查:
>>> random.seed(100) # to make it repeatable
>>> it2 = iter(lambda: random.randint(1,100), -1)
>>> list(itertools.islice(it2, 30, 52))
[45, 48, 81, 53, 27, 52, 60, 72, 36, 49, 21, 84, 82, 16, 24, 1, 78, 51, 19, 100, 73, 21]
21
重复了。
我是 Python 的新手,对以下作业有疑问。
import random
print(random.randint(1, 100))
如何计算重复的随机数(使用字典)?
输出应该是这样的:
>>> repeat (1, 100)
([random1, random2, random3, ...], number of loops until the first repetition is reached)
谢谢。
您可以只初始化一个集合,然后循环获取一个随机数并检查它是否已经在集合中,如果是则退出,否则将其添加到集合并继续。
不是使用字典,而是函数 repeat
:
import random
def repeat(a, b):
l = []
while True:
l.append(random.randint(a, b))
if len(set(l)) != len(l):
break
return l
print(repeat(1, 100))
输出:
[13, 76, 32, 41, 59, 34, 43, 91, 28, 17, 53, 20, 46, 67, 37, 88, 16, 6, 92, 34]
你可以保留一个列表,并在该列表中不断添加你的随机数,当你发现你的随机数已经在你的列表中时,你就打破循环注意这是一个 O(n) 解决方案正弦您需要在整个列表中找到该元素
import random
my_list = []
while True:
#Generate random number
i = random.randint(1, 100)
#If it is already in the list, break the loop
if i in my_list:
break
#Append random number to list
my_list.append(i)
print(my_list)
输出可能看起来像
[5, 58, 84, 53]
[5, 29, 64, 52, 69, 53, 72, 41, 58, 50, 4, 68, 67, 22, 90, 32, 45, 17, 47, 89, 55, 6, 7, 46, 37, 88]
[17, 65, 46, 84, 30, 100, 48, 31, 80, 97, 70, 86, 47, 81, 13, 85, 60, 63, 22, 68, 8, 36, 99]
.....
@6502 已经指出的 O(1) 建议是将随机数附加为字典的键,这样查找会更快 O(1)
import random
my_dict = {}
while True:
#Generate random number
i = random.randint(1, 100)
#If it is already in the keys of dict, break the loop
if i in my_dict:
break
#Append random number as key of dict with value 0
my_dict[i] = 0
print(list(my_dict.keys()))
我们实际上可以使用 timeit
模块来检查改进,尽管它并不明显,因为随机数大小只有 1-100
首先是列表方法
In [21]: import random
...:
...: def get_list():
...: my_list = []
...: while True:
...: #Generate random number
...: i = random.randint(1, 100)
...: #If it is already in the list, break the loop
...: if i in my_list:
...: break
...: #Append random number to list
...: my_list.append(i)
...: return my_list
...:
In [22]: %timeit get_list()
16.9 µs ± 720 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
然后是字典方法
In [27]:
In [27]: import random
...:
...: def get_list():
...: my_dict = {}
...: while True:
...: # Generate random number
...: i = random.randint(1, 100)
...: # If it is already in the keys of dict, break the loop
...: if i in my_dict:
...: break
...: # Append random number as key of dict with value 0
...: my_dict[i] = 0
In [29]: %timeit get_list()
16.1 µs ± 567 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但是如果我们使用 1-10000 的范围,差异是明显的
In [38]: import random
...:
...: def get_list(upper):
...:
...: my_list = []
...: while True:
...: # Generate random number
...: i = random.randint(1, upper)
...: # If it is already in the list, break the loop
...: if i in my_list:
...: break
...: # Append random number to list
...: my_list.append(i)
...:
In [39]: %timeit get_list(10000)
287 µs ± 5.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [40]: import random
...:
...: def get_list(upper):
...:
...: my_dict = {}
...:
...: while True:
...: # Generate random number
...: i = random.randint(1, upper)
...: # If it is already in the keys of dict, break the loop
...: if i in my_dict:
...: break
...: # Append random number as key of dict with value 0
...: my_dict[i] = 0
...:
In [41]: %timeit get_list(10000)
155 µs ± 2.48 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
您可以看到列表方法花费的时间几乎是字典方法的两倍!
如果不需要维护生成数字的顺序,可以使用字典来做到这一点。
import random
def repeat_generator(min, max):
random_dict = {}
while True:
random_number = random.randint(min, max)
if random_dict.get(random_number):
break
else:
random_dict[random_number] = 1
print(random_dict.keys())
试试下面的代码。这会将每个随机数添加到字典中,然后使用它来检查随机数是否已经存在。你可以使用其他数据结构做同样的事情,但是,因为你提到了字典,所以我在这里使用它。
import random
rand_dict = {}
i = 0
while True:
rand_num = random.randint(1,100)
if rand_num in rand_dict:
print("random number already in dict. rand_num = %s, Number of Loops = %s" %(rand_num, i))
break
else:
i += 1
rand_dict[rand_num] = 1
输出:
random number already in dict. rand_num = 90, Number of Loops = 11
set
比dict
更适合这里,因为你只是想记录重复,dict
中的值在这里没用,O(1)次检查重复set
:
import random
def repeat(a, b):
nums = set()
count = 0
while len(nums) == count:
nums.add(random.randint(a, b))
count += 1
return list(nums)
这是一个高级解决方案。
首先,创建一个随机数生成器:
>>> import random
>>> random.seed(100) # to make it repeatable
>>> it = iter(lambda: random.randint(1,100), -1)
这是函数的鲜为人知的形式 iter
:第一个参数是一个函数,在到达哨兵之前一直被调用。由于 randint
永远不会 return -1
,这是一个无限的随机数生成器:
>>> import itertools
>>> list(itertools.islice(it, 15))
[19, 59, 59, 99, 23, 91, 51, 94, 45, 56, 65, 15, 69, 16, 11]
>>> list(itertools.islice(it, 15))
[95, 59, 34, 7, 85, 83, 27, 43, 30, 40, 99, 27, 23, 19, 25]
您可以根据需要获得任意数量的随机数。 (函数 islice
采用迭代器的 "slice")。现在,我们在不知道数字的情况下取数字:
>>> seen = set()
>>> list(itertools.takewhile(lambda x: x not in seen and not seen.add(x), it))
[45, 48, 81, 53, 27, 52, 60, 72, 36, 49, 21, 84, 82, 16, 24, 1, 78, 51, 19, 100, 73]
注意副作用:我们创建一个空集 s
来存储看到的数字,并且对于每个 x
,我们测试 x
是否在 seen
中(我们之前看到x
)然后将x
添加到seen
。诀窍是 seen.add(x)
总是 return None
,因此 not seen.add(x)
总是 True
和 b and not seen.add(x) == b and True == b
.
检查:
>>> random.seed(100) # to make it repeatable
>>> it2 = iter(lambda: random.randint(1,100), -1)
>>> list(itertools.islice(it2, 30, 52))
[45, 48, 81, 53, 27, 52, 60, 72, 36, 49, 21, 84, 82, 16, 24, 1, 78, 51, 19, 100, 73, 21]
21
重复了。