Python 检查列表中元素之间是否存在差异
我正试图建立一个尽可能简单可行的启发式方法。从0到n,找到n个数字,使它们之间的所有差异都不同。这种启发式方法包括每次将标尺递增1。如果列表中已存在差异,请跳到下一个整数。因此标尺以[0,1]开始,差异列表=[1]。然后我们尝试将2添加到标尺[0,1,2],但这是不可行的,因为差异列表中已经存在差异(2-1=1)。然后我们尝试将3添加到标尺[0,1,3],这是可行的,因此差异列表变成[1,2,3],依此类推。以下是我到目前为止的收获:Python 检查列表中元素之间是否存在差异,python,python-3.x,heuristics,Python,Python 3.x,Heuristics,我正试图建立一个尽可能简单可行的启发式方法。从0到n,找到n个数字,使它们之间的所有差异都不同。这种启发式方法包括每次将标尺递增1。如果列表中已存在差异,请跳到下一个整数。因此标尺以[0,1]开始,差异列表=[1]。然后我们尝试将2添加到标尺[0,1,2],但这是不可行的,因为差异列表中已经存在差异(2-1=1)。然后我们尝试将3添加到标尺[0,1,3],这是可行的,因此差异列表变成[1,2,3],依此类推。以下是我到目前为止的收获: n = 5 positions = list(range(1
n = 5
positions = list(range(1,n+1))
Pos = []
Dist = []
difs = []
i = 0
while (i < len(positions)):
if len(Pos)==0:
Pos.append(0)
Dist.append(0)
elif len(Pos)==1:
Pos.append(1)
Dist.append(1)
else:
postest = Pos + [i] #check feasibility to enter the ruler
difs = [a-b for a in postest for b in postest if a > b]
if any (d in difs for d in Dist)==True:
pass
else:
for d in difs:
Dist.append(d)
Pos.append(i)
i += 1
n=5
位置=列表(范围(1,n+1))
Pos=[]
Dist=[]
difs=[]
i=0
而(ib时a在后测中a在后测中b在后测中a-b]
如果有(DIF中的d表示距离中的d)=真:
通过
其他:
对于DIF中的d:
附加区(d)
附加位置(i)
i+=1
然而,我不能让差异检查工作。有什么建议吗?为了提高效率,我倾向于使用一个集合来存储差异,因为它们有利于包含测试,并且您不关心顺序(可能直到您实际打印出来,此时您可以使用排序后的
)
您可以使用临时集存储正在测试的数字与当前拥有的数字之间的差异,然后将其添加到现有集,或者如果发现任何匹配项,则将其丢弃。(注意else
为循环设置块,如果未遇到break
,将执行该循环。)
n=5
i=0
VAL=[]
diff=set()
而len(vals)
显式循环值(而不是使用any
)是为了避免不必要地计算候选编号与所有现有值之间的差异,因为大多数候选编号都不成功,并且可以在找到第一个匹配项后提前中止循环
它也适用于VAL
作为一个集合,并使用add
而不是append
(尽管类似地,您可能希望在打印时使用sorted
)。在本例中,使用了一个列表,尽管原则上迭代顺序并不重要,但这段代码以相反的顺序进行迭代,以首先测试较小的差异,因为这样很可能会更快地拒绝不可用的候选项。在n=200的情况下对其进行测试,代码在反转时运行约0.2秒,在反转时运行约2.1秒;随着n
的增加,这种影响逐渐变得更加明显。当n=400时,分别用了1.7秒和27秒,有无反转
,这很好。它工作得又好又快。为什么在diffs |=diffs1中不可能使用diffs.add(diffs1)?@fsimoyama因为要添加集合diffs1
的每个成员,所以不希望将集合添加为diffs
的元素(而且无论如何都不允许这样做,因为集合元素必须是不可变的对象)。如果更清楚的话,diffs |=diffs1
可以替换为diffs=diffs.union(diffs1)
。@fsimoyama实际上我在这里做的是生成一个新的集合,它就是union,并将它重新分配给名称diffs
,然后丢弃旧的集合。对每个元素执行diffs.add()
操作时,在diffs1
的元素上循环可能会更快(对于足够小的集diffs1
和足够大的集diffs
)。如果你想的话,我会让你去比较计时。@fsimoyama实际上是在做些修改,似乎集合中有一个我忘记了的update
方法。我将其更改为diffs.update(diffs1)
@fsimoyama现在已更改(并测试了功能,但没有计时)。想一想update
,比如列表上的extend
方法,当然是无序的。但是它应该是我在记事之前提到的显式循环的一个更快的等价物,也就是说,它将元素添加到现有的集合中,而不是创建一个新的集合。
n = 5
i = 0
vals = []
diffs = set()
while len(vals) < n:
diffs1 = set()
for j in reversed(vals):
diff = i - j
if diff in diffs:
break
diffs1.add(diff)
else:
vals.append(i)
diffs.update(diffs1)
i += 1
print(vals, sorted(diffs))