[英]Undertanding the disimilarities between 2 similar codes with different results in python while loop
[英]Results are different between python and mysql for similar command
我當時使用python創建字典,但是隨着我的數據變大,我開始出現內存錯誤,所以我以為我會節省內存,只是將數據寫到數據庫中,但是結果卻不一樣。 我認為這與defaultdict的行為有關(但我不確定)。
這是有效的python代碼(它基本上建立了一個值表):
from collections import defaultdict
data = [2,5,10]
target_sum = 100
# T[x, i] is True if 'x' can be solved
# by a linear combination of data[:i+1]
T = defaultdict(bool) # all values are False by default
T[0, 0] = True # base case
for i, x in enumerate(data): # i is index, x is data[i]
for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
for c in range(s / x + 1):
if T[s - c * x, i]:
T[s, i+1] = True
#check the python dict results
count = 0
for x in T:
if T[x] == True:
print x, ':', T[x]
count = count +1
print 'total count is ', count
#False is 152 and True is 250. Total is: 402
結果是一個很大的值表(您可以在注釋中看到細分。這是我想要的正確結果),但是當我更改第一個for語句的最后一行以添加到數據庫而不是本地dict時,結果有所不同。
這是有問題的我修改后的代碼:
cursor = conn.cursor ()
cursor = conn.cursor ()
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
CREATE TABLE data_table
(
value CHAR(80),
state BOOL
)
""")
#with database
for i, x in enumerate(data): # i is index, x is data[i]
for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
for c in range(s / x + 1):
cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
if cursor.rowcount == 0:
#print 'nothing found, adding'
cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', False)""" % ([s - c * x, i]))
elif cursor.rowcount == 1:
cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % ([s - c * x, i]))
#print 'record updated'
conn.commit()
#False is 17 and True is 286. Total is: 303
總結一下(如果您不想運行代碼),defaultdict在查詢某些內容時會創建一個錯誤的條目(在這種情況下, if T[s - c * x, i]:
以便復制此功能我對值進行mysql查找,如果不存在則創建它,如果存在則將其設置為true。 我非常懷疑我無法正確復制功能
我唯一想的另一件事是python將結果顯示為(222, 0) : False
222,0 (222, 0) : False
但是mysql正在[222,0]不確定是否會有所作為。
您的兩個示例未更新相同的密鑰:
# First example
if T[s - c * x, i]:
T[s, i+1] = True
# Key is (s, i+1)
# Second example
elif cursor.rowcount == 1:
cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % ([s - c * x, i]))
# Key is (s - c * x, i)
IMO僅將True案例存儲在數據庫中會更有意義,這可能會使您的程序更簡單。 否則,您還需要檢查數據庫中是否存在(s, i+1)
如果存在則將其更新為True,否則將其創建為新行。
PS我也錯過了將(0, 0)
為True的命令。 在創建數據庫之后,這不應該放在插入內容中嗎?
更新 :在您的代碼中還發現了另一個問題:select命令僅檢查行是否存在 ,而不是行的值。 為了正確地復制您的第一個示例,您的代碼應為:
cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', True)""" % ([0, 0]))
conn.commit()
# Inserted the (0,0) case
for i, x in enumerate(data):
for s in range(target_sum + 1):
for c in range(s / x + 1):
cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
if cursor.rowcount == 0:
cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', False)""" % ([s - c * x, i]))
elif cursor.rowcount == 1:
(value, state) = cursor.fetchone() # Gets the state
if state: # equivalent to your if in the first example
insertOrUpdate(conn, [s, i+1])
conn.commit()
更改的行已注釋。
更新2 :這還不夠...(正如我所說,如果只存儲True值,則要簡單得多)。 為了便於閱讀,將零件移到了if
內部:
def insertOrUpdate(conn, key):
cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % key)
if cursor.rowcount == 0:
# Insert as True if not exists
cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', True)""" % key)
elif cursor.rowcount == 1:
(value, state) = cursor.fetchone()
if !state:
# Update as True, if it was False
cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % key)
更新3:相比之下,僅存儲True值就可以使程序變得更簡單。 它還使用更少的磁盤空間,花費更少的時間,並且表現得更像defaultdict。
cursor = conn.cursor ()
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
CREATE TABLE data_table(
value CHAR(80)
)
""")
cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [0, 0])
conn.commit()
for i, x in enumerate(data): # i is index, x is data[i]
for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
for c in range(s / x + 1):
cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
if cursor.rowcount == 1:
cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % [s, i+1])
if cursor.rowcount == 0:
cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [s, i+1])
conn.commit()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.