好吧,我写了下面的代码来找到任意数量概率的联合(关于这个主题的精彩文章:https://www.thoughtco.com/probability-union-of-three-sets-more-3126263):
#Finds all Intersections
def intersection_finder1(poss, intersection_number):
#Make Lists of descending possibilities intersection_number times, Works for 2, not 3
sub_posses = []
use = poss
sub_posses.append(use)
for i in range(intersection_number - 1):
#print use[(i+1):], intersection_number
sub_posses.append(use[(i+1):])
return sub_posses
def sub_poss_modifier(sub_posses):
for x in range(len(sub_posses)):
del sub_posses[x][0]
return sub_posses
def intersection_finder2(sub_posses, intersection_number, ongoing_sum=0):
#Iterate over lists for list_item_number_1
#Increment lists by one
#Repeat for last_list length times,
#Commented out below are debugging things
multi = 1
for y in range(len(sub_posses[-1])):
for i in range(len(sub_posses)):
multi = multi * sub_posses[i][y]
#print multi, sub_posses[i][y], intersection_number
#print "-----------RESTART------------"
ongoing_sum += multi
multi = 1
if len(sub_posses[-1]) > 1:
new_lt = sub_poss_modifier(sub_posses)
return intersection_finder2(new_lt, intersection_number, ongoing_sum)
return ongoing_sum
def combiner(poss):
#Sums Possbilities
total = sum(poss)
ongoing_total = total
#Adds/Subtracts Combinations
for i in range(2, len(poss) + 1):
#Somehow, poss is changing. I have no idea how.
#Say poss is [1/2.0, 1/2.0, 1/2.0]. If you put that in, the function works. If you put poss in, it doesn't
print poss
sub_poss = intersection_finder1(poss, i)
aors = intersection_finder2(sub_poss, i)
#print aors, i
if i % 2 == 0:
ongoing_total -= aors
else:
ongoing_total += aors
#Returns total Possbility
return ongoing_total
print combiner([1/2.0, 1/2.0, 1/2.0])
它有效,但只有在我进行特定更改时才会插入变量 poss 的值来代替自身。例如(唯一的变化是组合器的第9行):
#Finds all Intersections
def intersection_finder1(poss, intersection_number):
#Make Lists of descending possibilities intersection_number times, Works for 2, not 3
sub_posses = []
use = poss
sub_posses.append(use)
for i in range(intersection_number - 1):
#print use[(i+1):], intersection_number
sub_posses.append(use[(i+1):])
return sub_posses
def sub_poss_modifier(sub_posses):
for x in range(len(sub_posses)):
del sub_posses[x][0]
return sub_posses
def intersection_finder2(sub_posses, intersection_number, ongoing_sum=0):
#Iterate over lists for list_item_number_1
#Increment lists by one
#Repeat for last_list length times,
#Commented out below are debugging things
multi = 1
for y in range(len(sub_posses[-1])):
for i in range(len(sub_posses)):
multi = multi * sub_posses[i][y]
#print multi, sub_posses[i][y], intersection_number
#print "-----------RESTART------------"
ongoing_sum += multi
multi = 1
if len(sub_posses[-1]) > 1:
new_lt = sub_poss_modifier(sub_posses)
return intersection_finder2(new_lt, intersection_number, ongoing_sum)
return ongoing_sum
def combiner(poss):
#Sums Possbilities
total = sum(poss)
ongoing_total = total
#Adds/Subtracts Combinations
for i in range(2, len(poss) + 1):
#Somehow, poss is changing. I have no idea how.
#Say poss is [1/2.0, 1/2.0, 1/2.0]. If you put that in, the function works. If you put poss in, it doesn't
#print poss
sub_poss = intersection_finder1([1/2.0, 1/2.0, 1/2.0], i)
aors = intersection_finder2(sub_poss, i)
#print aors, i
if i % 2 == 0:
ongoing_total -= aors
else:
ongoing_total += aors
#Returns total Possbility
return ongoing_total
print combiner([1/2.0, 1/2.0, 1/2.0])
通过稍微调试,我发现变量 poss 在for循环的每次迭代中都会发生变化 - 从而产生错误的答案。此外,它只在代码块#1中发生变化;在代码块#2中, poss 保持不变。到目前为止,我还没有找到任何在任何函数中重新定义或改变 poss 的实例。此外,即使我确实在某处改变了 poss ,代码块#1和#2之间的唯一区别是函数 combiner 的第九行中的列表。然而,块#2产生了正确的答案,而块#1则没有。
块#1的终端输出(打印 poss ): [0.5,0.5,0.5] [0.5,0.5] 0.75
块#2的终端输出(打印 poss ): [0.5,0.5,0.5] [0.5,0.5,0.5] 0.875
到目前为止,为了防止 poss 改变,同时保持一定程度的一般用途,我试图重新定义它并重命名它。我可以做些什么来阻止 poss 改变,同时让它计算不同的概率就像更改变量一样简单?
顺便说一下,我对编程很新,所以任何建议让我的代码更好或我自己是一个更好的程序员作为一个整体将非常感激。
答案 0 :(得分:0)
"到目前为止,我还没有找到任何重新定义或重新定义的实例 改变任何功能。"
您可以非常清楚地更改函数参数posse
引用的对象。您基本上会将intersection_finder1
的结果传递给intersection_finder2
(apt名称...)在intersection_finder1
中,您将posse
追加到sub_posses
。换句话说,在集合的分区中,您使用对象本身来表示不正确的子集。
def intersection_finder1(poss, intersection_number):
#Make Lists of descending possibilities intersection_number times, Works for 2, not 3
sub_posses = []
use = poss # NOT MAKING A COPY
这说现在也可以通过使用
来引用拥有的对象 sub_posses.append(use) # now sub_posses includes posse
for i in range(intersection_number - 1):
#print use[(i+1):], intersection_number
sub_posses.append(use[(i+1):])
return sub_posses
现在,在intersection_finder2
sub_poss_modifier
,sub_posses
点击def sub_poss_modifier(sub_posses):
for x in range(len(sub_posses)):
del sub_posses[x][0]
return sub_posses
:
sub_posses[0]
明确修改posse
的地方,即posse.copy()
解决方案? 制作副本。你可以使用内置的列表方法poss[:]
,或者很好理解的python copy-idiom,def intersection_finder1(poss, intersection_number):
#Make Lists of descending possibilities intersection_number times, Works for 2, not 3
sub_posses = []
use = poss.copy()
。
-Wall
在其他地方,您不想共享对象,但想要一个相同值的列表......
为了更好地掌握Python变量和值的工作方式,我建议阅读所有Ned Batchelder的Facts and myths about Python names and values。
此外,您应该知道这些操作会产生shallow copies。如果您的数据结构比不可变对象列表(例如列表列表或dicts列表)更复杂,则可能需要深层复制。你应该知道区别。
答案 1 :(得分:0)
当您传递列表时,它将作为对象传递,而不是作为副本传递,任何赋值都将引用该对象作为引用。
您要将poss
追加到sub_posses
中的intersection_finder1()
。即使分配给use
,这也可以通过其引用而不是副本进行附加。
在sub_poss_modifier()
中删除sub_posses
的部分内容。这实际上也删除了poss
的元素。
解决方案是在追加sub_posses
中的intersection_finder1()
时制作副本:
sub_posses.append(use[:])