2015-04-02 108 views
-2

我有一個有趣的問題。我 - 對於狗屎和咯咯 - 試圖寫一個程序很快。我把它歸結爲2行,但它有一個競爭條件,我不明白爲什麼。下面是它的要點:Python中的競態條件

imports... 
...[setattr(__main__, 'f', [1, 2, ..]), reduce(...random.choice(f)...)][1]... 

每過一段時間,將產生以下異常。但不總是。這是我的問題。我懷疑執行的順序不能保證,特別是因爲我使用列表技巧 - 我會假設解釋器可以預測setattr()返回None,並知道我只選擇了第二件事列表,所以它將實際的setattr()推遲到稍後。但它只是有時會發生。有任何想法嗎? CPython會自動線程化一些東西,如地圖,過濾器,減少呼叫嗎?

Traceback (most recent call last): 
    File "/usr/lib64/python3.4/random.py", line 253, in choice 
    i = self._randbelow(len(seq)) 
    File "/usr/lib64/python3.4/random.py", line 230, in _randbelow 
    r = getrandbits(k)   # 0 <= r < 2**k 
ValueError: number of bits must be greater than zero 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "test4.py", line 2, in <module> 
    print(" ".join([setattr(n,'f',open(sys.argv[1],"r").read().replace("\n"," ").split(" ")),setattr(n,'m',c.defaultdict(list)),g.reduce(lambda p,e:p+[r.choice(m[p[-1]])],range(int(sys.argv[2])),[r.choice(list(filter(lambda x:[m[x[0]].append(x[1]),x[0].isupper()][1],zip(f[:-1],f[1:]))))[0]])][2])) 
    File "test4.py", line 2, in <lambda> 
    print(" ".join([setattr(n,'f',open(sys.argv[1],"r").read().replace("\n"," ").split(" ")),setattr(n,'m',c.defaultdict(list)),g.reduce(lambda p,e:p+[r.choice(m[p[-1]])],range(int(sys.argv[2])),[r.choice(list(filter(lambda x:[m[x[0]].append(x[1]),x[0].isupper()][1],zip(f[:-1],f[1:]))))[0]])][2])) 
    File "/usr/lib64/python3.4/random.py", line 255, in choice 
    raise IndexError('Cannot choose from an empty sequence') 
IndexError: Cannot choose from an empty sequence 

我試圖修改全局()和VAR()使用SETATTR()的insetad,但似乎並沒有幫助(同一個異常序列)。

下面是實際的代碼:

import sys,collections as c,random as r,functools as g,__main__ as n 
print(" ".join([setattr(n,'f',open(sys.argv[1],"r").read().replace("\n"," ").split(" ")),setattr(n,'m',c.defaultdict(list)),g.reduce(lambda p,e:p+[r.choice(m[p[-1]])],range(int(sys.argv[2])),[r.choice(list(filter(lambda x:[m[x[0]].append(x[1]),x[0].isupper()][1],zip(f[:-1],f[1:]))))[0]])][2])) 

如果你很好奇:這是一個文本文件閱讀,產生一個馬爾可夫模型,並吐出了一句。

+0

「這是不確定的,我不知道爲什麼......'random.choice'」 – KSFT 2015-04-02 00:15:49

+0

是的 - 這是一個random.choice從一個序列中選擇,如果已分配'f',該序列不應該爲空一個值。 – hugelgupf 2015-04-02 00:16:49

+1

真的有必要在一行代碼中完成所有工作嗎? – Barmar 2015-04-02 00:17:16

回答

1

好吧,這裏是實際發生的情況:在我的文本產生,我有時打文件中的最後一個字(在某些情況下,根據該文件,沒有一個可能的繼任狀態)。因此,我試圖在這種情況下從空列表中選擇。

1
random.choice() 

那麼,當然這是不確定的。如果你非常小心,可以將僞隨機數發生器的種子設置爲常量,並希望每次都能製作相同的序列。這很有可能會起作用。

random.seed(42); ... 
+0

我不是那個意思。我說我有時會得到例外,有時候我不會。 – hugelgupf 2015-04-02 00:18:41

+0

他並不是說價值觀是不確定的,他聲稱操作的順序是非確定性的,有時會造成錯誤。 – Barmar 2015-04-02 00:19:06

+0

@hugelgupf:你*說*。你在你的問題中完全說錯了,你應該說點別的。 – user2357112 2015-04-02 00:19:52