列表中范围内的Python
我的问题的概念是识别一个随机数的字母列表中范围内的Python,python,Python,我的问题的概念是识别一个随机数的字母 ra_list保存随机浮点数 e_list包含字母和范围 当前代码标识字符串匹配,并在具有相同值的B和C字母之间随机化 ra_list = [6, 7, 7] e_list = [(6, 'A'), (7, 'B'), (7, 'C'), (8, 'E')] test_dict = {} for key,val in e_list: test_dict.setdefault(key,[]).append(val) import r
ra_list
保存随机浮点数
e_list
包含字母和范围
当前代码标识字符串匹配,并在具有相同值的B和C字母之间随机化
ra_list = [6, 7, 7]
e_list = [(6, 'A'), (7, 'B'), (7, 'C'), (8, 'E')]
test_dict = {}
for key,val in e_list:
test_dict.setdefault(key,[]).append(val)
import random
for i in ra_list:
cate = random.choice(test_dict.get(i,[0]))
if cate != 0:
print i,cate
然而,我的问题是我在ra_list
中有浮点数,并且希望实现范围-我几乎没有python经验。如何操作当前代码并解决范围内的问题<代码>e_列表将始终按升序排列。例如:
ra_list = [6.25, 7.5, 7.6]
e_list = [(6, 'A'), (7.4, 'B'), (7.4, 'C'), (7.7, 'E')]
output = (6.25, A), (7.5, B or C), (7.6, B or C)
ra_list
中小于e_list
的第一个值的值应得到A
,大于最后一个值的值应为e
一种简单的方法是创建字典键的排序列表,并找到一个比输入值小但具有最大值的值浮动
from collections import OrderedDict
import random
ra_list = [5, 6.25, 7.5, 7.6]
e_list = [(6, 'A'), (7.4, 'B'), (7.4, 'C'), (7.7, 'E')]
test_dict = OrderedDict()
for key,val in e_list:
test_dict.setdefault(key,[]).append(val)
key_list = list(test_dict.keys())
min_key = key_list[0]
for i in ra_list:
max_key = min_key
for key in key_list:
if i >= key:
max_key = key
else:
break
cate = random.choice(test_dict.get(max_key))
print( i,cate)
这比将输入浮点值转换为整数要复杂得多,但其好处是可以将浮点值添加到(数字、字母)对中
编辑2:
根据评论更新原始答案。您可以执行以下操作:
In [1]: e_list = [(6, 'A'), (7, 'B'), (7, 'C'), (8, 'E')]
In [2]: import random
In [3]: from collections import OrderedDict
In [4]: choices_dict = OrderedDict()
In [5]: for x in e_list:
ra = x[0]
e = x[1]
if ra in choices_dict:
choices_dict[ra].append(e)
else:
choices_dict[ra] = [e]
In [6]: choices_dict
Out [6]: OrderedDict([(6, ['A']), (7, ['B', 'C']), (8, ['E'])])
choices\u dict
是一本包含限制和字母的字典
我们创建一个函数get_e_value
,它将为给定的ra
提供e
的值
如果该值在某个范围内,则从选项中返回下限的随机字母列表。否则,返回最高范围的字母
In [7]: def get_e_value(my_number):
limits = choices_dict.keys()
limits_count = len(limits)
for x in range(limits_count):
if (my_number <= limits[x]) or (x!= limits_count-1 and my_number<limits[x+1]): # check if number lies between a range
choices = choices_dict[limits[x]]
return random.choice(choices)
last_key = limits[-1] # number is beyond range
return random.choice(choices_dict[last_key]) # return largest range letter
In [8]: ra_list = [1.3, 2.5, 5, 6.3, 7.5, 8.5]
In [9]: final_output = [(x, get_e_value(x)) for x in ra_list]
In [10]: final_output
Out [10]: [(1.3, 'A'), (2.5, 'A'), (5, 'A'), (6.3, 'A'), (7.5, 'C'), (8.5, 'E')]
[7]中的:def get_e_值(我的_编号):
限制=选择\u dict.keys()
限制\u计数=长度(限制)
对于范围内的x(限制\u计数):
如果(my_number,您可以使用对分模块,使用每个子元组中的第一个元素作为对分的键,这将为您提供一个运行时间,即O(N log N)
,而不是二次:
from bisect import bisect
from random import choice
def pair(l, l2):
# use first element from each tuple as the key
keys = [r[0] for r in l2]
for i in l:
# find the index i would go in keys to keep order
ind = bisect(keys, i)
# make sure we don't wrap araound i.e 0 to -1
# and don't fall of the end
ind = ind - 1 if ind > 0 else ind
yield (i, e_list[ind][1])
输出:
In [32]: ra_list = [5.5, 6.25, 7.5, 7.6, 7.7,9.0]
In [33]: e_list = [(6, 'A'), (7.4, 'B'), (7.4, 'C'), (7.7, 'E')]
In [34]: list(pair(ra_list, e_list))
Out[34]: [(5.5, 'A'), (6.25, 'A'), (7.5, 'C'), (7.6, 'C'), (7.7, 'E'), (9.0, 'E')]
如果您确实希望对重复值进行随机选择,则逻辑完全相同,您只需再次将它们分组到dict中,并检查每个对应键的值/列表长度是否包含多个元素,如果它确实随机选择了一个元素:
def pair(l, l2):
dct = {}
for a, b in l2:
dct.setdefault(a, []).append(b)
keys = [r[0] for r in l2]
for i in l:
ind = bisect(keys, i)
print(ind,i)
ind = ind - 1 if 0 < ind else ind
val = dct[e_list[ind][0]]
yield ((i, val[0]) if len(val) == 1 else (i, choice(val)))
不确定是否出现了完全匹配的结果,如果它像上面的7.7
那样,它将使用相应的值,如果它应该是其他值,那么它仍然只需要不断的工作,因此运行时将停留在N log N
您希望代码输出“B”或“C”,或者它是哪个不重要?这不重要如果是B或C,因为它们有相同的值。我目前的代码将产生B或C,如果E是7,它也会在B、C或E中迭代。这是我正在努力解决的范围。我不确定你这里的范围是什么意思,你想实现什么,对不起。ra_列表中的值会小于或大于E_列表中的值吗此外,e_列表似乎是上升而不是下降如果r_列表中有7.7
会发生什么?它似乎为列表中的每个元素生成0?这很奇怪,我的输出符合op的要求:6.25a7.5b7.6b
。您使用哪一版本的python?它不会为5打印任何内容,这是正确的。但是,这是正确的根据我对op问题的理解,te是未定义的。但是,如果在这种情况下要求将5
匹配到dict中的最小值,可以通过将max_key=None
更改为max_key=sorted(test_dict.keys())[0]
yep,用sorted(test_dict)对一个进行排序
或者最好再次使用OrderedDict,因为数据已经排序好了。现在,您使用的是ra_列表中的元组,而不是浮点数。您需要使用元组第一个值来创建映射。您可以说ra_key=i[0]
作为ra_列表中i的中的第一个语句,然后检查如果ra_key>=key:
7.5应为B或CE@PadraicCunningham是的!你说得对。更新了ans。
In [63]: ra_list = [5.5, 6.25, 7.5, 7.6, 7.7, 7.8, 9.0]
In [64]: e_list = [(6, 'A'), (7.4, 'B'), (7.4, 'C'), (7.7, 'E'), (7.7, "F")]
In [65]: print(list(pair(ra_list, e_list)))
[(5.5, 'A'), (6.25, 'A'), (7.5, 'C'), (7.6, 'C'), (7.7, 'F'), (7.8, 'F'), (9.0, 'E')]
In [66]: print(list(pair(ra_list, e_list)))
[(5.5, 'A'), (6.25, 'A'), (7.5, 'B'), (7.6, 'C'), (7.7, 'F'), (7.8, 'F'), (9.0, 'E')]
In [67]: print(list(pair(ra_list, e_list)))
[(5.5, 'A'), (6.25, 'A'), (7.5, 'B'), (7.6, 'B'), (7.7, 'F'), (7.8, 'F'), (9.0, 'F')]
In [68]: print(list(pair(ra_list, e_list)))
[(5.5, 'A'), (6.25, 'A'), (7.5, 'C'), (7.6, 'B'), (7.7, 'F'), (7.8, 'F'), (9.0, 'E')]
In [69]: print(list(pair(ra_list, e_list)))
[(5.5, 'A'), (6.25, 'A'), (7.5, 'C'), (7.6, 'C'), (7.7, 'E'), (7.8, 'F'), (9.0, 'E')]