Python 求两个相乘为20的整数。我能把这段代码写得更详细吗;蟒蛇的;?
我做了这段代码,在一个列表中找到两个整数(在本例中为[2,4,5,1,6,40,-1]),它们相乘到20。一开始我有点受困,但添加一个函数解决了我的问题。我向我的一个程序员朋友展示了这段代码,他说我可以让这段代码更“pythonic”,但我不知道怎么做 代码如下:Python 求两个相乘为20的整数。我能把这段代码写得更详细吗;蟒蛇的;?,python,python-3.x,Python,Python 3.x,我做了这段代码,在一个列表中找到两个整数(在本例中为[2,4,5,1,6,40,-1]),它们相乘到20。一开始我有点受困,但添加一个函数解决了我的问题。我向我的一个程序员朋友展示了这段代码,他说我可以让这段代码更“pythonic”,但我不知道怎么做 代码如下: num_list = [2,4,5,1,6,40,-1] def get_mult_num(given_list): for i in given_list: for j in range(i+1, len(
num_list = [2,4,5,1,6,40,-1]
def get_mult_num(given_list):
for i in given_list:
for j in range(i+1, len(given_list)): #for j not to be == i and to be in the list
mult_two_numbers = i * j
if mult_two_numbers == 20:
return i,j
print(get_mult_num(num_list))
[(i,j)对于num_列表中的i对于num_列表中的j如果i我可以考虑使用列表理解。如果给定列表中存在多个这样的对,这也有助于找到它们
num_list = [2,4,5,1,6,40,-1]
mult_num = [(num_list[i],num_list[j]) for i in range(len(num_list)) for j in range(i+1, len(num_list)) if num_list[i]*num_list[j] == 20]
print mult_num
输出:
[(4, 5)]
这是我对它的看法,它使用:
我想你的朋友可能在暗示当它使代码更干净时使用它(有时不会)。我不一定认为它是“非Python的”,你在使用标准的Python习语循环你的数据并产生一个结果,或者None
并非您生成了正确的实现。虽然i
在给定的\u数上循环,j
在从i+2
到len(给定的\u数)的整数上循环
,将给定列表中的值与索引混合?对于您的样本输入,您从半开放范围[4,7]、[6,7]、[7,7](空)、[3,7]、[8,7](空)、[42,7)(空)和[42,7](空)中获取j
[1,7)。它产生正确答案完全是运气,而不是因为正确性;如果你给你的函数列表[2,10]
,它找不到解决方案!您想再次循环给定的\u编号,受限于切片,或者从当前索引i
开始生成索引,但是您的外部循环也需要添加一个enumerate()
调用:
for ii, i in enumerate(given_numbers):
for j in given_numbers[ii + 1:]:
# ...
或
所有这些都远没有它所能做到的那么有效;Python标准库为您提供了生成i,j
对的工具,而无需嵌套for
循环或切片或其他形式的过滤
您的双循环应该生成整数输入,因此使用生成唯一的i,j
对:
from itertools import combinations
def get_mult_num(given_list):
return [(i, j) for i, j in combinations(given_list, 2) if i * j == 20]
这假设可以有零个或多个这样的解决方案,而不仅仅是一个解决方案
如果您只需要第一个结果或None
,可以使用:
接下来,您可能不想产生所有可能的组合,而是想将问题颠倒过来。如果您将给定的_列表
转换为一个集合,您可以轻松地检查目标数字20是否可以被任何给定的数字干净地无余数地除掉,并且除法的结果更大,并且也是数字集合中的整数.这会在线性时间内给你一个答案
您可以通过用小于目标值平方根的数字除以来进一步限制搜索,因为您在输入数字中找不到匹配的更大的值(给定一个数字n
,它的平方根s
,根据定义s*(s+1)
将大于n
)
如果我们向函数中添加目标编号的参数,并将其设为a,则会得到:
def gen_factors_for(target, numbers):
possible_j = set(numbers)
limit = abs(target) ** 0.5
for i in numbers:
if abs(i) < limit and target % i == 0:
j = target // i
if j in possible_j and abs(j) > abs(i):
yield i, j
def gen_系数(目标、数字):
可能的_j=设置(数字)
极限=abs(目标)**0.5
以数字表示的i:
如果abs(i)<限制和目标%i==0:
j=目标//i
如果j在可能的_j和abs(j)>abs(i):
收益率i,j
这种方法比测试所有排列要快得多,特别是当您需要找到所有可能的因素时。请注意,我在这里创建了两个函数生成器,以平衡比较:
>>> import random, operator
>>> from timeit import Timer
>>> def gen_factors_for_division(target, numbers):
... possible_j = set(numbers)
... limit = abs(target) ** 0.5
... for i in numbers:
... if abs(i) < limit and target % i == 0:
... j = target // i
... if j in possible_j and abs(j) > abs(i):
... yield i, j
...
>>> def gen_factors_for_combinations(target, given_list):
... return ((i, j) for i, j in combinations(given_list, 2) if i * j == target)
...
>>> numbers = [random.randint(-10000, 10000) for _ in range(100)]
>>> targets = [operator.mul(*random.sample(set(numbers), 2)) for _ in range(5)]
>>> targets += [t + random.randint(1, 100) for t in targets] # add likely-to-be-unsolvable numbers
>>> for (label, t) in (('first match:', 'next({}, None)'), ('all matches:', 'list({})')):
... print(label)
... for f in (gen_factors_for_division, gen_factors_for_combinations):
... test = t.format('f(t, n)')
... timer = Timer(
... f"[{test} for t in ts]",
... 'from __main__ import targets as ts, numbers as n, f')
... count, total = timer.autorange()
... print(f"{f.__name__:>30}: {total / count * 1000:8.3f}ms")
...
first match:
gen_factors_for_division: 0.219ms
gen_factors_for_combinations: 4.664ms
all matches:
gen_factors_for_division: 0.259ms
gen_factors_for_combinations: 3.326ms
>导入随机,运算符
>>>从timeit导入计时器
>>>def gen_部门的系数(目标、数字):
…可能的_j=设置(数字)
…极限=abs(目标)**0.5
…以数字表示的i:
…如果abs(i)<限制和目标%i==0:
…j=目标//i
…如果j在可能的情况下_j和abs(j)>abs(i):
…屈服i,j
...
>>>def gen_系数_用于_组合(目标,给定_列表):
…如果i*j==目标,则返回组合中i,j的(i,j)(给定的_列表,2)
...
>>>数字=[random.randint(-10000,10000)表示范围(100)]
>>>目标=[operator.mul(*random.sample(set(number),2))用于范围(5)]
>>>目标+=[t+random.randint(1100)表示目标中的t]#添加可能无法解决的数字
>>>对于(('first match:','next({},None'),('all matches:','list({}'))中的(标签,t):
…打印(标签)
…对于f in(第二代因子用于第二代划分,第二代因子用于第二代组合):
…test=t.format('f(t,n)'
…计时器=计时器(
…f“[{test}对于ts中的t]”,
…'从_umain__;导入目标为ts,数字为n,f')
…计数,总计=timer.autorange()
…打印(f“{f.\u name}>30}:{total/count*1000:8.3f}ms”)
...
第一场比赛:
分区的GENU系数:0.219ms
组合的发电机系数:4.664ms
所有匹配项:
分区的发电机系数:0.259ms
组合的发电机系数:3.326ms
请注意,我生成了10个不同的随机目标,以避免两种方法中出现幸运的最佳情况。您可以通过使用itertools.combines(而不是嵌套循环)来查找所有的数字对,从而使其更具pythonic性。不总是这样,但经常在索引上迭代,如中针对范围内的I(len(L)):
比直接在值上迭代要少一些pythonic,如L:
中的v:
Python还允许您通过yield
关键字将函数生成生成器,这样,您就可以通过迭代函数调用获得每一对,而不是返回第一对乘以20的结果
import itertools
def factors(x, numbers):
""" Generate all pairs in list of numbers that multiply to x.
"""
for a, b in itertools.combinations(numbers, 2):
if a * b == x:
yield (a, b)
numbers = [2, 4, 5, 1, 6, 40, -1]
for pair in factors(20, numbers):
print(pair)
我想到了这个。它稍微颠倒了方法,在num\u列表中搜索所需的配对伙伴
def get_mult_num(given_list):
multiplies_to_20 = (
(i, j) for i, j in combinations(given_list, 2)
if i * j == 20)
return next(multiplies_to_20, None)
def gen_factors_for(target, numbers):
possible_j = set(numbers)
limit = abs(target) ** 0.5
for i in numbers:
if abs(i) < limit and target % i == 0:
j = target // i
if j in possible_j and abs(j) > abs(i):
yield i, j
>>> import random, operator
>>> from timeit import Timer
>>> def gen_factors_for_division(target, numbers):
... possible_j = set(numbers)
... limit = abs(target) ** 0.5
... for i in numbers:
... if abs(i) < limit and target % i == 0:
... j = target // i
... if j in possible_j and abs(j) > abs(i):
... yield i, j
...
>>> def gen_factors_for_combinations(target, given_list):
... return ((i, j) for i, j in combinations(given_list, 2) if i * j == target)
...
>>> numbers = [random.randint(-10000, 10000) for _ in range(100)]
>>> targets = [operator.mul(*random.sample(set(numbers), 2)) for _ in range(5)]
>>> targets += [t + random.randint(1, 100) for t in targets] # add likely-to-be-unsolvable numbers
>>> for (label, t) in (('first match:', 'next({}, None)'), ('all matches:', 'list({})')):
... print(label)
... for f in (gen_factors_for_division, gen_factors_for_combinations):
... test = t.format('f(t, n)')
... timer = Timer(
... f"[{test} for t in ts]",
... 'from __main__ import targets as ts, numbers as n, f')
... count, total = timer.autorange()
... print(f"{f.__name__:>30}: {total / count * 1000:8.3f}ms")
...
first match:
gen_factors_for_division: 0.219ms
gen_factors_for_combinations: 4.664ms
all matches:
gen_factors_for_division: 0.259ms
gen_factors_for_combinations: 3.326ms
import itertools
def factors(x, numbers):
""" Generate all pairs in list of numbers that multiply to x.
"""
for a, b in itertools.combinations(numbers, 2):
if a * b == x:
yield (a, b)
numbers = [2, 4, 5, 1, 6, 40, -1]
for pair in factors(20, numbers):
print(pair)
for val in num_list:
if 20 / val in num_list:
print(val, int(20/val))